@expressive/mvc 0.5.0 → 0.6.0
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 +49 -58
- package/lib/index.esm.js +271 -228
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +270 -228
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -17,11 +17,11 @@ function issues(register) {
|
|
|
17
17
|
return Library;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const Oops$
|
|
20
|
+
const Oops$b = issues({
|
|
21
21
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
22
22
|
});
|
|
23
23
|
function suspend(source, key) {
|
|
24
|
-
const error = Oops$
|
|
24
|
+
const error = Oops$b.NotReady(source.subject, key);
|
|
25
25
|
const promise = new Promise(resolve => {
|
|
26
26
|
const release = source.addListener(forKey => {
|
|
27
27
|
if (forKey == key)
|
|
@@ -61,101 +61,170 @@ function mayRetry(fn) {
|
|
|
61
61
|
return compute();
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
const Oops$
|
|
64
|
+
const Oops$a = issues({
|
|
65
65
|
BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
66
66
|
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
67
|
-
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}]
|
|
67
|
+
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
68
|
+
FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
|
|
69
|
+
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
70
|
+
ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
68
71
|
});
|
|
69
72
|
const INFO = new WeakMap();
|
|
70
73
|
const KEYS = new WeakMap();
|
|
71
74
|
const ORDER = new WeakMap();
|
|
72
|
-
function get(
|
|
75
|
+
function get(arg0, arg1, arg2) {
|
|
73
76
|
return apply(function get(key) {
|
|
74
|
-
const { subject
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
arg1 = undefined;
|
|
77
|
+
const { subject } = this;
|
|
78
|
+
const computeRequired = arg1 === true || arg2 === true;
|
|
79
|
+
const factoryRequired = arg1 !== false && arg2 !== false;
|
|
80
|
+
let getter;
|
|
79
81
|
// Easy mistake, using a peer, will always be unresolved.
|
|
80
|
-
if (typeof
|
|
81
|
-
throw Oops$
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let sub;
|
|
96
|
-
let order = ORDER.get(this);
|
|
97
|
-
if (!order)
|
|
98
|
-
ORDER.set(this, order = []);
|
|
99
|
-
const compute = (initial) => {
|
|
100
|
-
try {
|
|
101
|
-
return setter.call(sub.proxy, sub.proxy);
|
|
102
|
-
}
|
|
103
|
-
catch (err) {
|
|
104
|
-
Oops$b.Failed(subject, key, initial).warn();
|
|
105
|
-
throw err;
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
const refresh = () => {
|
|
109
|
-
let value;
|
|
110
|
-
try {
|
|
111
|
-
value = compute(false);
|
|
112
|
-
}
|
|
113
|
-
catch (e) {
|
|
114
|
-
console.error(e);
|
|
115
|
-
}
|
|
116
|
-
finally {
|
|
117
|
-
if (state.get(key) !== value) {
|
|
118
|
-
state.set(key, value);
|
|
119
|
-
this.update(key);
|
|
120
|
-
return value;
|
|
82
|
+
if (typeof arg0 == "symbol")
|
|
83
|
+
throw Oops$a.PeerNotAllowed(subject, key);
|
|
84
|
+
if (typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
|
|
85
|
+
throw Oops$a.BadSource(subject, key, arg0);
|
|
86
|
+
this.state.set(key, undefined);
|
|
87
|
+
const init = () => {
|
|
88
|
+
let source = this;
|
|
89
|
+
let setter;
|
|
90
|
+
if (typeof arg0 == "function") {
|
|
91
|
+
const result = mayRetry(() => arg0.call(subject, key, subject));
|
|
92
|
+
if (typeof result == "function")
|
|
93
|
+
setter = result;
|
|
94
|
+
else {
|
|
95
|
+
getter = factoryMode(this, result, key, factoryRequired);
|
|
96
|
+
return;
|
|
121
97
|
}
|
|
122
98
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (source !== this) {
|
|
126
|
-
refresh();
|
|
99
|
+
else if (arg0 instanceof Promise) {
|
|
100
|
+
getter = factoryMode(this, arg0, key, factoryRequired);
|
|
127
101
|
return;
|
|
128
102
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
103
|
+
else if (typeof arg1 == "function") {
|
|
104
|
+
// replace source controller in-case it is different
|
|
105
|
+
source = ensure(arg0);
|
|
106
|
+
setter = arg1;
|
|
107
|
+
}
|
|
108
|
+
else
|
|
109
|
+
throw new Error(`Factory argument cannot be ${arg1}`);
|
|
110
|
+
getter = computeMode(this, source, setter, key, computeRequired);
|
|
133
111
|
};
|
|
134
|
-
|
|
135
|
-
sub = getSource().subscribe(update);
|
|
112
|
+
if (typeof arg0 == "function" && factoryRequired)
|
|
136
113
|
try {
|
|
137
|
-
|
|
138
|
-
state.set(key, value);
|
|
139
|
-
return value;
|
|
140
|
-
}
|
|
141
|
-
catch (e) {
|
|
142
|
-
throw e;
|
|
114
|
+
init();
|
|
143
115
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
116
|
+
catch (err) {
|
|
117
|
+
Oops$a.ComputeFailed(subject, key).warn();
|
|
118
|
+
throw err;
|
|
147
119
|
}
|
|
148
|
-
};
|
|
149
|
-
state.set(key, undefined);
|
|
150
|
-
INFO.set(refresh, info);
|
|
151
120
|
return () => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return value;
|
|
121
|
+
if (!getter)
|
|
122
|
+
init();
|
|
123
|
+
return getter();
|
|
156
124
|
};
|
|
157
125
|
});
|
|
158
126
|
}
|
|
127
|
+
function factoryMode(self, output, key, required) {
|
|
128
|
+
const { subject, state } = self;
|
|
129
|
+
let pending;
|
|
130
|
+
let error;
|
|
131
|
+
if (output instanceof Promise) {
|
|
132
|
+
state.set(key, undefined);
|
|
133
|
+
pending = output
|
|
134
|
+
.catch(err => error = err)
|
|
135
|
+
.then(val => {
|
|
136
|
+
state.set(key, val);
|
|
137
|
+
return val;
|
|
138
|
+
})
|
|
139
|
+
.finally(() => {
|
|
140
|
+
pending = undefined;
|
|
141
|
+
self.update(key);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
state.set(key, output);
|
|
145
|
+
const suspend = () => {
|
|
146
|
+
if (required === false)
|
|
147
|
+
return undefined;
|
|
148
|
+
const issue = Oops$a.NotReady(subject, key);
|
|
149
|
+
Object.assign(pending, {
|
|
150
|
+
message: issue.message,
|
|
151
|
+
stack: issue.stack
|
|
152
|
+
});
|
|
153
|
+
throw pending;
|
|
154
|
+
};
|
|
155
|
+
return () => {
|
|
156
|
+
if (error)
|
|
157
|
+
throw error;
|
|
158
|
+
if (pending)
|
|
159
|
+
return suspend();
|
|
160
|
+
if (state.has(key))
|
|
161
|
+
return state.get(key);
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function computeMode(self, source, setter, key, required) {
|
|
165
|
+
const { subject, state } = self;
|
|
166
|
+
let sub;
|
|
167
|
+
let order = ORDER.get(self);
|
|
168
|
+
if (!order)
|
|
169
|
+
ORDER.set(self, order = []);
|
|
170
|
+
const compute = (initial) => {
|
|
171
|
+
try {
|
|
172
|
+
return setter.call(sub.proxy, sub.proxy);
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
Oops$a.Failed(subject, key, initial).warn();
|
|
176
|
+
throw err;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const refresh = () => {
|
|
180
|
+
let value;
|
|
181
|
+
try {
|
|
182
|
+
value = compute(false);
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
console.error(e);
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
if (state.get(key) !== value) {
|
|
189
|
+
state.set(key, value);
|
|
190
|
+
self.update(key);
|
|
191
|
+
return value;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
const update = (_key, source) => {
|
|
196
|
+
if (source !== self) {
|
|
197
|
+
refresh();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
let pending = KEYS.get(self);
|
|
201
|
+
if (!pending)
|
|
202
|
+
KEYS.set(self, pending = []);
|
|
203
|
+
pending.push(refresh);
|
|
204
|
+
};
|
|
205
|
+
const create = () => {
|
|
206
|
+
sub = source.subscribe(update);
|
|
207
|
+
try {
|
|
208
|
+
const value = compute(true);
|
|
209
|
+
state.set(key, value);
|
|
210
|
+
return value;
|
|
211
|
+
}
|
|
212
|
+
catch (e) {
|
|
213
|
+
throw e;
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
sub.commit();
|
|
217
|
+
order.push(refresh);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
INFO.set(refresh, key);
|
|
221
|
+
return () => {
|
|
222
|
+
const value = sub ? state.get(key) : create();
|
|
223
|
+
if (value === undefined && required)
|
|
224
|
+
throw suspend(self, key);
|
|
225
|
+
return value;
|
|
226
|
+
};
|
|
227
|
+
}
|
|
159
228
|
function flush(control) {
|
|
160
229
|
const pending = KEYS.get(control);
|
|
161
230
|
if (!pending)
|
|
@@ -165,14 +234,14 @@ function flush(control) {
|
|
|
165
234
|
const compute = pending
|
|
166
235
|
.sort((a, b) => list.indexOf(b) - list.indexOf(a))
|
|
167
236
|
.pop();
|
|
168
|
-
const
|
|
237
|
+
const key = INFO.get(compute);
|
|
169
238
|
if (!control.frame.has(key))
|
|
170
239
|
compute();
|
|
171
240
|
}
|
|
172
241
|
KEYS.delete(control);
|
|
173
242
|
}
|
|
174
243
|
|
|
175
|
-
const Oops$
|
|
244
|
+
const Oops$9 = issues({
|
|
176
245
|
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
177
246
|
});
|
|
178
247
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
@@ -185,7 +254,7 @@ function createEffect(callback) {
|
|
|
185
254
|
if (unSet instanceof Promise)
|
|
186
255
|
unSet = undefined;
|
|
187
256
|
if (unSet && typeof unSet !== "function")
|
|
188
|
-
throw Oops$
|
|
257
|
+
throw Oops$9.BadCallback();
|
|
189
258
|
};
|
|
190
259
|
}
|
|
191
260
|
function createValueEffect(callback) {
|
|
@@ -201,65 +270,11 @@ function createValueEffect(callback) {
|
|
|
201
270
|
if (typeof out == "function")
|
|
202
271
|
unSet = out;
|
|
203
272
|
else
|
|
204
|
-
throw Oops$
|
|
273
|
+
throw Oops$9.BadCallback();
|
|
205
274
|
};
|
|
206
275
|
}
|
|
207
276
|
|
|
208
|
-
|
|
209
|
-
constructor(parent, onUpdate) {
|
|
210
|
-
this.onUpdate = onUpdate;
|
|
211
|
-
this.active = false;
|
|
212
|
-
this.dependant = new Set();
|
|
213
|
-
const proxy = create(parent.subject);
|
|
214
|
-
const using = new Map();
|
|
215
|
-
defineProperty(proxy, LOCAL, { value: this });
|
|
216
|
-
defineProperty(this, "proxy", {
|
|
217
|
-
configurable: true,
|
|
218
|
-
get() {
|
|
219
|
-
if (UPDATE.has(proxy))
|
|
220
|
-
setTimeout(() => UPDATE.delete(proxy), 0);
|
|
221
|
-
return proxy;
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
const release = parent.addListener(key => {
|
|
225
|
-
if (!this.active)
|
|
226
|
-
return;
|
|
227
|
-
const handler = using.get(key);
|
|
228
|
-
let notify;
|
|
229
|
-
if (typeof handler == "function") {
|
|
230
|
-
const callback = handler();
|
|
231
|
-
if (callback === true)
|
|
232
|
-
notify = this.onUpdate(key, parent);
|
|
233
|
-
}
|
|
234
|
-
else if (handler === true)
|
|
235
|
-
notify = this.onUpdate(key, parent);
|
|
236
|
-
if (!notify)
|
|
237
|
-
return;
|
|
238
|
-
const notate = () => {
|
|
239
|
-
UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
|
|
240
|
-
};
|
|
241
|
-
parent.waiting.add(notate);
|
|
242
|
-
parent.waiting.add(notify);
|
|
243
|
-
});
|
|
244
|
-
this.commit = () => {
|
|
245
|
-
this.active = true;
|
|
246
|
-
this.dependant.forEach(x => x.commit());
|
|
247
|
-
return this.release;
|
|
248
|
-
};
|
|
249
|
-
this.release = () => {
|
|
250
|
-
this.dependant.forEach(x => x.release());
|
|
251
|
-
release();
|
|
252
|
-
};
|
|
253
|
-
this.add = (key, value) => {
|
|
254
|
-
if (value !== undefined)
|
|
255
|
-
using.set(key, value);
|
|
256
|
-
else if (!using.has(key))
|
|
257
|
-
using.set(key, true);
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const Oops$9 = issues({
|
|
277
|
+
const Oops$8 = issues({
|
|
263
278
|
Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
|
|
264
279
|
StrictUpdate: () => `Strict update() did not find pending updates.`,
|
|
265
280
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
@@ -342,7 +357,7 @@ class Model {
|
|
|
342
357
|
const invoke = (key) => {
|
|
343
358
|
if (!key) {
|
|
344
359
|
clear();
|
|
345
|
-
reject(Oops$
|
|
360
|
+
reject(Oops$8.Timeout(select, typeof argument == "number"
|
|
346
361
|
? `${argument}ms`
|
|
347
362
|
: `lifetime of ${this}`));
|
|
348
363
|
}
|
|
@@ -429,11 +444,11 @@ class Model {
|
|
|
429
444
|
arg = undefined;
|
|
430
445
|
}
|
|
431
446
|
if (!frame.size && arg === true)
|
|
432
|
-
return Promise.reject(Oops$
|
|
447
|
+
return Promise.reject(Oops$8.StrictUpdate());
|
|
433
448
|
return {
|
|
434
449
|
then: (callback) => {
|
|
435
450
|
if (!callback)
|
|
436
|
-
throw Oops$
|
|
451
|
+
throw Oops$8.NoChaining();
|
|
437
452
|
if (frame.size || arg !== false)
|
|
438
453
|
waiting.add(() => {
|
|
439
454
|
callback(getUpdate(this));
|
|
@@ -475,7 +490,63 @@ class Model {
|
|
|
475
490
|
}
|
|
476
491
|
}
|
|
477
492
|
|
|
493
|
+
class Subscriber {
|
|
494
|
+
constructor(parent, onUpdate) {
|
|
495
|
+
this.onUpdate = onUpdate;
|
|
496
|
+
this.active = false;
|
|
497
|
+
this.dependant = new Set();
|
|
498
|
+
const proxy = create(parent.subject);
|
|
499
|
+
const using = new Map();
|
|
500
|
+
const listen = this.add = (key, value) => {
|
|
501
|
+
if (value !== undefined)
|
|
502
|
+
using.set(key, value);
|
|
503
|
+
else if (!using.has(key))
|
|
504
|
+
using.set(key, true);
|
|
505
|
+
};
|
|
506
|
+
LISTEN.set(proxy, listen);
|
|
507
|
+
defineProperty(proxy, LOCAL, { value: this });
|
|
508
|
+
defineProperty(this, "proxy", {
|
|
509
|
+
configurable: true,
|
|
510
|
+
get() {
|
|
511
|
+
if (UPDATE.has(proxy))
|
|
512
|
+
setTimeout(() => UPDATE.delete(proxy), 0);
|
|
513
|
+
return proxy;
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
const release = parent.addListener(key => {
|
|
517
|
+
if (!this.active)
|
|
518
|
+
return;
|
|
519
|
+
const handler = using.get(key);
|
|
520
|
+
let notify;
|
|
521
|
+
if (typeof handler == "function") {
|
|
522
|
+
const callback = handler();
|
|
523
|
+
if (callback === true)
|
|
524
|
+
notify = this.onUpdate(key, parent);
|
|
525
|
+
}
|
|
526
|
+
else if (handler === true)
|
|
527
|
+
notify = this.onUpdate(key, parent);
|
|
528
|
+
if (!notify)
|
|
529
|
+
return;
|
|
530
|
+
const notate = () => {
|
|
531
|
+
UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
|
|
532
|
+
};
|
|
533
|
+
parent.waiting.add(notate);
|
|
534
|
+
parent.waiting.add(notify);
|
|
535
|
+
});
|
|
536
|
+
this.commit = () => {
|
|
537
|
+
this.active = true;
|
|
538
|
+
this.dependant.forEach(x => x.commit());
|
|
539
|
+
return this.release;
|
|
540
|
+
};
|
|
541
|
+
this.release = () => {
|
|
542
|
+
this.dependant.forEach(x => x.release());
|
|
543
|
+
release();
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
478
548
|
const UPDATE = new WeakMap();
|
|
549
|
+
const LISTEN = new WeakMap();
|
|
479
550
|
const CONTROL = Symbol("CONTROL");
|
|
480
551
|
function getUpdate(subject) {
|
|
481
552
|
return UPDATE.get(subject);
|
|
@@ -506,9 +577,9 @@ class Controller {
|
|
|
506
577
|
enumerable: false,
|
|
507
578
|
set: this.ref(key),
|
|
508
579
|
get() {
|
|
509
|
-
const
|
|
510
|
-
if (
|
|
511
|
-
|
|
580
|
+
const listen = LISTEN.get(this);
|
|
581
|
+
if (listen)
|
|
582
|
+
listen(key);
|
|
512
583
|
return state.get(key);
|
|
513
584
|
}
|
|
514
585
|
});
|
|
@@ -635,9 +706,10 @@ function apply(fn, label) {
|
|
|
635
706
|
get() {
|
|
636
707
|
if (!state.has(key) && suspense)
|
|
637
708
|
throw suspend(control, key);
|
|
709
|
+
const listen = LISTEN.get(this);
|
|
638
710
|
const local = this[LOCAL];
|
|
639
|
-
if (
|
|
640
|
-
|
|
711
|
+
if (listen)
|
|
712
|
+
listen(key);
|
|
641
713
|
return onGet
|
|
642
714
|
? onGet(local)
|
|
643
715
|
: state.get(key);
|
|
@@ -705,7 +777,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
705
777
|
});
|
|
706
778
|
}
|
|
707
779
|
|
|
708
|
-
const Oops$
|
|
780
|
+
const Oops$7 = issues({
|
|
709
781
|
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
710
782
|
});
|
|
711
783
|
function act(task) {
|
|
@@ -713,7 +785,7 @@ function act(task) {
|
|
|
713
785
|
let pending = false;
|
|
714
786
|
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
715
787
|
if (pending)
|
|
716
|
-
return Promise.reject(Oops$
|
|
788
|
+
return Promise.reject(Oops$7.DuplicatePending(key));
|
|
717
789
|
pending = true;
|
|
718
790
|
this.update(key);
|
|
719
791
|
try {
|
|
@@ -749,81 +821,6 @@ function ref(callback) {
|
|
|
749
821
|
});
|
|
750
822
|
}
|
|
751
823
|
|
|
752
|
-
const Oops$7 = issues({
|
|
753
|
-
NonOptional: (Parent, key) => `Property ${Parent}.${key} is marked as required.`,
|
|
754
|
-
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
755
|
-
Failed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
756
|
-
});
|
|
757
|
-
function put(factory, argument) {
|
|
758
|
-
return apply(function set(key) {
|
|
759
|
-
const { subject, state } = this;
|
|
760
|
-
const required = argument === true ||
|
|
761
|
-
argument === undefined;
|
|
762
|
-
let pending;
|
|
763
|
-
let error;
|
|
764
|
-
const init = () => {
|
|
765
|
-
const output = typeof factory == "function" ?
|
|
766
|
-
mayRetry(() => factory.call(subject, key, subject)) :
|
|
767
|
-
factory;
|
|
768
|
-
if (output instanceof Promise) {
|
|
769
|
-
pending = output
|
|
770
|
-
.catch(err => error = err)
|
|
771
|
-
.then(val => {
|
|
772
|
-
state.set(key, val);
|
|
773
|
-
return val;
|
|
774
|
-
})
|
|
775
|
-
.finally(() => {
|
|
776
|
-
pending = undefined;
|
|
777
|
-
this.update(key);
|
|
778
|
-
});
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
state.set(key, output);
|
|
782
|
-
return output;
|
|
783
|
-
};
|
|
784
|
-
if (required)
|
|
785
|
-
try {
|
|
786
|
-
init();
|
|
787
|
-
}
|
|
788
|
-
catch (err) {
|
|
789
|
-
Oops$7.Failed(subject, key).warn();
|
|
790
|
-
throw err;
|
|
791
|
-
}
|
|
792
|
-
const suspend = () => {
|
|
793
|
-
if (required === false)
|
|
794
|
-
return undefined;
|
|
795
|
-
const issue = Oops$7.NotReady(subject, key);
|
|
796
|
-
Object.assign(pending, {
|
|
797
|
-
message: issue.message,
|
|
798
|
-
stack: issue.stack
|
|
799
|
-
});
|
|
800
|
-
throw pending;
|
|
801
|
-
};
|
|
802
|
-
const get = () => {
|
|
803
|
-
if (pending)
|
|
804
|
-
return suspend();
|
|
805
|
-
if (error)
|
|
806
|
-
throw error;
|
|
807
|
-
if (state.has(key))
|
|
808
|
-
return state.get(key);
|
|
809
|
-
const output = init();
|
|
810
|
-
return pending
|
|
811
|
-
? suspend()
|
|
812
|
-
: output;
|
|
813
|
-
};
|
|
814
|
-
const set = typeof argument == "function"
|
|
815
|
-
? createValueEffect(argument)
|
|
816
|
-
: (value) => {
|
|
817
|
-
if (value === undefined && required)
|
|
818
|
-
throw Oops$7.NonOptional(subject, key);
|
|
819
|
-
};
|
|
820
|
-
return {
|
|
821
|
-
set,
|
|
822
|
-
get
|
|
823
|
-
};
|
|
824
|
-
});
|
|
825
|
-
}
|
|
826
|
-
|
|
827
824
|
function set(value, argument) {
|
|
828
825
|
if (!(1 in arguments)) {
|
|
829
826
|
argument = value;
|
|
@@ -987,31 +984,77 @@ function createProxy(emit, watch) {
|
|
|
987
984
|
const Parent = new WeakMap();
|
|
988
985
|
const Oops$6 = issues({
|
|
989
986
|
BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
|
|
987
|
+
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
990
988
|
});
|
|
991
989
|
function use$1(input, argument) {
|
|
992
990
|
return apply(function use(key) {
|
|
993
991
|
const { state, subject } = this;
|
|
992
|
+
const required = argument !== false;
|
|
993
|
+
let pending;
|
|
994
|
+
let error;
|
|
995
|
+
let get = (_local) => state.get(key);
|
|
994
996
|
if (typeof input === "function")
|
|
995
|
-
input =
|
|
997
|
+
input = /^[A-Z]/.test(input.name)
|
|
998
|
+
? new input() : input;
|
|
996
999
|
else if (input && typeof input !== "object")
|
|
997
1000
|
throw Oops$6.BadArgument(typeof input);
|
|
998
1001
|
if (input instanceof Map || input instanceof Set)
|
|
999
1002
|
return keyed(this, key, input);
|
|
1000
|
-
|
|
1003
|
+
const onUpdate = (next) => {
|
|
1001
1004
|
state.set(key, next);
|
|
1002
1005
|
if (next) {
|
|
1006
|
+
get = getRecursive(key, this);
|
|
1003
1007
|
Parent.set(next, subject);
|
|
1004
1008
|
ensure(next);
|
|
1005
1009
|
}
|
|
1006
1010
|
if (typeof argument == "function")
|
|
1007
1011
|
argument(next);
|
|
1008
1012
|
return true;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1013
|
+
};
|
|
1014
|
+
const suspend = () => {
|
|
1015
|
+
if (required === false)
|
|
1016
|
+
return;
|
|
1017
|
+
const issue = Oops$6.NotReady(subject, key);
|
|
1018
|
+
Object.assign(pending, {
|
|
1019
|
+
message: issue.message,
|
|
1020
|
+
stack: issue.stack
|
|
1021
|
+
});
|
|
1022
|
+
throw pending;
|
|
1023
|
+
};
|
|
1024
|
+
const initialize = () => {
|
|
1025
|
+
const output = typeof input == "function" ?
|
|
1026
|
+
mayRetry(() => input.call(subject, subject)) :
|
|
1027
|
+
input;
|
|
1028
|
+
if (output instanceof Promise) {
|
|
1029
|
+
pending = output
|
|
1030
|
+
.catch(err => error = err)
|
|
1031
|
+
.then(val => {
|
|
1032
|
+
onUpdate(val);
|
|
1033
|
+
return val;
|
|
1034
|
+
})
|
|
1035
|
+
.finally(() => {
|
|
1036
|
+
pending = undefined;
|
|
1037
|
+
this.update(key);
|
|
1038
|
+
});
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
onUpdate(output);
|
|
1042
|
+
};
|
|
1043
|
+
if (input !== undefined && required)
|
|
1044
|
+
initialize();
|
|
1012
1045
|
return {
|
|
1013
1046
|
set: onUpdate,
|
|
1014
|
-
|
|
1047
|
+
get(local) {
|
|
1048
|
+
if (pending)
|
|
1049
|
+
return suspend();
|
|
1050
|
+
if (error)
|
|
1051
|
+
throw error;
|
|
1052
|
+
if (!state.has(key))
|
|
1053
|
+
initialize();
|
|
1054
|
+
if (pending)
|
|
1055
|
+
return suspend();
|
|
1056
|
+
return get(local);
|
|
1057
|
+
}
|
|
1015
1058
|
};
|
|
1016
1059
|
});
|
|
1017
1060
|
}
|
|
@@ -1458,5 +1501,5 @@ class Global extends MVC {
|
|
|
1458
1501
|
}
|
|
1459
1502
|
}
|
|
1460
1503
|
|
|
1461
|
-
export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, MVC as default, get, has,
|
|
1504
|
+
export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, MVC as default, get, has, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
|
|
1462
1505
|
//# sourceMappingURL=index.esm.js.map
|