@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.js
CHANGED
|
@@ -25,11 +25,11 @@ function issues(register) {
|
|
|
25
25
|
return Library;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const Oops$
|
|
28
|
+
const Oops$b = 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$b.NotReady(source.subject, key);
|
|
33
33
|
const promise = new Promise(resolve => {
|
|
34
34
|
const release = source.addListener(forKey => {
|
|
35
35
|
if (forKey == key)
|
|
@@ -69,101 +69,170 @@ function mayRetry(fn) {
|
|
|
69
69
|
return compute();
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
const Oops$
|
|
72
|
+
const Oops$a = issues({
|
|
73
73
|
BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
74
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}]
|
|
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.`
|
|
76
79
|
});
|
|
77
80
|
const INFO = new WeakMap();
|
|
78
81
|
const KEYS = new WeakMap();
|
|
79
82
|
const ORDER = new WeakMap();
|
|
80
|
-
function get(
|
|
83
|
+
function get(arg0, arg1, arg2) {
|
|
81
84
|
return apply(function get(key) {
|
|
82
|
-
const { subject
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
arg1 = undefined;
|
|
85
|
+
const { subject } = this;
|
|
86
|
+
const computeRequired = arg1 === true || arg2 === true;
|
|
87
|
+
const factoryRequired = arg1 !== false && arg2 !== false;
|
|
88
|
+
let getter;
|
|
87
89
|
// Easy mistake, using a peer, will always be unresolved.
|
|
88
|
-
if (typeof
|
|
89
|
-
throw Oops$
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
let sub;
|
|
104
|
-
let order = ORDER.get(this);
|
|
105
|
-
if (!order)
|
|
106
|
-
ORDER.set(this, order = []);
|
|
107
|
-
const compute = (initial) => {
|
|
108
|
-
try {
|
|
109
|
-
return setter.call(sub.proxy, sub.proxy);
|
|
110
|
-
}
|
|
111
|
-
catch (err) {
|
|
112
|
-
Oops$b.Failed(subject, key, initial).warn();
|
|
113
|
-
throw err;
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
const refresh = () => {
|
|
117
|
-
let value;
|
|
118
|
-
try {
|
|
119
|
-
value = compute(false);
|
|
120
|
-
}
|
|
121
|
-
catch (e) {
|
|
122
|
-
console.error(e);
|
|
123
|
-
}
|
|
124
|
-
finally {
|
|
125
|
-
if (state.get(key) !== value) {
|
|
126
|
-
state.set(key, value);
|
|
127
|
-
this.update(key);
|
|
128
|
-
return value;
|
|
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;
|
|
129
105
|
}
|
|
130
106
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (source !== this) {
|
|
134
|
-
refresh();
|
|
107
|
+
else if (arg0 instanceof Promise) {
|
|
108
|
+
getter = factoryMode(this, arg0, key, factoryRequired);
|
|
135
109
|
return;
|
|
136
110
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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);
|
|
141
119
|
};
|
|
142
|
-
|
|
143
|
-
sub = getSource().subscribe(update);
|
|
120
|
+
if (typeof arg0 == "function" && factoryRequired)
|
|
144
121
|
try {
|
|
145
|
-
|
|
146
|
-
state.set(key, value);
|
|
147
|
-
return value;
|
|
148
|
-
}
|
|
149
|
-
catch (e) {
|
|
150
|
-
throw e;
|
|
122
|
+
init();
|
|
151
123
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
124
|
+
catch (err) {
|
|
125
|
+
Oops$a.ComputeFailed(subject, key).warn();
|
|
126
|
+
throw err;
|
|
155
127
|
}
|
|
156
|
-
};
|
|
157
|
-
state.set(key, undefined);
|
|
158
|
-
INFO.set(refresh, info);
|
|
159
128
|
return () => {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return value;
|
|
129
|
+
if (!getter)
|
|
130
|
+
init();
|
|
131
|
+
return getter();
|
|
164
132
|
};
|
|
165
133
|
});
|
|
166
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
|
+
function computeMode(self, source, setter, key, required) {
|
|
173
|
+
const { subject, state } = self;
|
|
174
|
+
let sub;
|
|
175
|
+
let order = ORDER.get(self);
|
|
176
|
+
if (!order)
|
|
177
|
+
ORDER.set(self, order = []);
|
|
178
|
+
const compute = (initial) => {
|
|
179
|
+
try {
|
|
180
|
+
return setter.call(sub.proxy, sub.proxy);
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
Oops$a.Failed(subject, key, initial).warn();
|
|
184
|
+
throw err;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const refresh = () => {
|
|
188
|
+
let value;
|
|
189
|
+
try {
|
|
190
|
+
value = compute(false);
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
console.error(e);
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
if (state.get(key) !== value) {
|
|
197
|
+
state.set(key, value);
|
|
198
|
+
self.update(key);
|
|
199
|
+
return value;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
const update = (_key, source) => {
|
|
204
|
+
if (source !== self) {
|
|
205
|
+
refresh();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
let pending = KEYS.get(self);
|
|
209
|
+
if (!pending)
|
|
210
|
+
KEYS.set(self, pending = []);
|
|
211
|
+
pending.push(refresh);
|
|
212
|
+
};
|
|
213
|
+
const create = () => {
|
|
214
|
+
sub = source.subscribe(update);
|
|
215
|
+
try {
|
|
216
|
+
const value = compute(true);
|
|
217
|
+
state.set(key, value);
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
throw e;
|
|
222
|
+
}
|
|
223
|
+
finally {
|
|
224
|
+
sub.commit();
|
|
225
|
+
order.push(refresh);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
INFO.set(refresh, key);
|
|
229
|
+
return () => {
|
|
230
|
+
const value = sub ? state.get(key) : create();
|
|
231
|
+
if (value === undefined && required)
|
|
232
|
+
throw suspend(self, key);
|
|
233
|
+
return value;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
167
236
|
function flush(control) {
|
|
168
237
|
const pending = KEYS.get(control);
|
|
169
238
|
if (!pending)
|
|
@@ -173,14 +242,14 @@ function flush(control) {
|
|
|
173
242
|
const compute = pending
|
|
174
243
|
.sort((a, b) => list.indexOf(b) - list.indexOf(a))
|
|
175
244
|
.pop();
|
|
176
|
-
const
|
|
245
|
+
const key = INFO.get(compute);
|
|
177
246
|
if (!control.frame.has(key))
|
|
178
247
|
compute();
|
|
179
248
|
}
|
|
180
249
|
KEYS.delete(control);
|
|
181
250
|
}
|
|
182
251
|
|
|
183
|
-
const Oops$
|
|
252
|
+
const Oops$9 = issues({
|
|
184
253
|
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
185
254
|
});
|
|
186
255
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
@@ -193,7 +262,7 @@ function createEffect(callback) {
|
|
|
193
262
|
if (unSet instanceof Promise)
|
|
194
263
|
unSet = undefined;
|
|
195
264
|
if (unSet && typeof unSet !== "function")
|
|
196
|
-
throw Oops$
|
|
265
|
+
throw Oops$9.BadCallback();
|
|
197
266
|
};
|
|
198
267
|
}
|
|
199
268
|
function createValueEffect(callback) {
|
|
@@ -209,65 +278,11 @@ function createValueEffect(callback) {
|
|
|
209
278
|
if (typeof out == "function")
|
|
210
279
|
unSet = out;
|
|
211
280
|
else
|
|
212
|
-
throw Oops$
|
|
281
|
+
throw Oops$9.BadCallback();
|
|
213
282
|
};
|
|
214
283
|
}
|
|
215
284
|
|
|
216
|
-
|
|
217
|
-
constructor(parent, onUpdate) {
|
|
218
|
-
this.onUpdate = onUpdate;
|
|
219
|
-
this.active = false;
|
|
220
|
-
this.dependant = new Set();
|
|
221
|
-
const proxy = create(parent.subject);
|
|
222
|
-
const using = new Map();
|
|
223
|
-
defineProperty(proxy, LOCAL, { value: this });
|
|
224
|
-
defineProperty(this, "proxy", {
|
|
225
|
-
configurable: true,
|
|
226
|
-
get() {
|
|
227
|
-
if (UPDATE.has(proxy))
|
|
228
|
-
setTimeout(() => UPDATE.delete(proxy), 0);
|
|
229
|
-
return proxy;
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
const release = parent.addListener(key => {
|
|
233
|
-
if (!this.active)
|
|
234
|
-
return;
|
|
235
|
-
const handler = using.get(key);
|
|
236
|
-
let notify;
|
|
237
|
-
if (typeof handler == "function") {
|
|
238
|
-
const callback = handler();
|
|
239
|
-
if (callback === true)
|
|
240
|
-
notify = this.onUpdate(key, parent);
|
|
241
|
-
}
|
|
242
|
-
else if (handler === true)
|
|
243
|
-
notify = this.onUpdate(key, parent);
|
|
244
|
-
if (!notify)
|
|
245
|
-
return;
|
|
246
|
-
const notate = () => {
|
|
247
|
-
UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
|
|
248
|
-
};
|
|
249
|
-
parent.waiting.add(notate);
|
|
250
|
-
parent.waiting.add(notify);
|
|
251
|
-
});
|
|
252
|
-
this.commit = () => {
|
|
253
|
-
this.active = true;
|
|
254
|
-
this.dependant.forEach(x => x.commit());
|
|
255
|
-
return this.release;
|
|
256
|
-
};
|
|
257
|
-
this.release = () => {
|
|
258
|
-
this.dependant.forEach(x => x.release());
|
|
259
|
-
release();
|
|
260
|
-
};
|
|
261
|
-
this.add = (key, value) => {
|
|
262
|
-
if (value !== undefined)
|
|
263
|
-
using.set(key, value);
|
|
264
|
-
else if (!using.has(key))
|
|
265
|
-
using.set(key, true);
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
const Oops$9 = issues({
|
|
285
|
+
const Oops$8 = issues({
|
|
271
286
|
Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
|
|
272
287
|
StrictUpdate: () => `Strict update() did not find pending updates.`,
|
|
273
288
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
@@ -350,7 +365,7 @@ class Model {
|
|
|
350
365
|
const invoke = (key) => {
|
|
351
366
|
if (!key) {
|
|
352
367
|
clear();
|
|
353
|
-
reject(Oops$
|
|
368
|
+
reject(Oops$8.Timeout(select, typeof argument == "number"
|
|
354
369
|
? `${argument}ms`
|
|
355
370
|
: `lifetime of ${this}`));
|
|
356
371
|
}
|
|
@@ -437,11 +452,11 @@ class Model {
|
|
|
437
452
|
arg = undefined;
|
|
438
453
|
}
|
|
439
454
|
if (!frame.size && arg === true)
|
|
440
|
-
return Promise.reject(Oops$
|
|
455
|
+
return Promise.reject(Oops$8.StrictUpdate());
|
|
441
456
|
return {
|
|
442
457
|
then: (callback) => {
|
|
443
458
|
if (!callback)
|
|
444
|
-
throw Oops$
|
|
459
|
+
throw Oops$8.NoChaining();
|
|
445
460
|
if (frame.size || arg !== false)
|
|
446
461
|
waiting.add(() => {
|
|
447
462
|
callback(getUpdate(this));
|
|
@@ -483,7 +498,63 @@ class Model {
|
|
|
483
498
|
}
|
|
484
499
|
}
|
|
485
500
|
|
|
501
|
+
class Subscriber {
|
|
502
|
+
constructor(parent, onUpdate) {
|
|
503
|
+
this.onUpdate = onUpdate;
|
|
504
|
+
this.active = false;
|
|
505
|
+
this.dependant = new Set();
|
|
506
|
+
const proxy = create(parent.subject);
|
|
507
|
+
const using = new Map();
|
|
508
|
+
const listen = this.add = (key, value) => {
|
|
509
|
+
if (value !== undefined)
|
|
510
|
+
using.set(key, value);
|
|
511
|
+
else if (!using.has(key))
|
|
512
|
+
using.set(key, true);
|
|
513
|
+
};
|
|
514
|
+
LISTEN.set(proxy, listen);
|
|
515
|
+
defineProperty(proxy, LOCAL, { value: this });
|
|
516
|
+
defineProperty(this, "proxy", {
|
|
517
|
+
configurable: true,
|
|
518
|
+
get() {
|
|
519
|
+
if (UPDATE.has(proxy))
|
|
520
|
+
setTimeout(() => UPDATE.delete(proxy), 0);
|
|
521
|
+
return proxy;
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
const release = parent.addListener(key => {
|
|
525
|
+
if (!this.active)
|
|
526
|
+
return;
|
|
527
|
+
const handler = using.get(key);
|
|
528
|
+
let notify;
|
|
529
|
+
if (typeof handler == "function") {
|
|
530
|
+
const callback = handler();
|
|
531
|
+
if (callback === true)
|
|
532
|
+
notify = this.onUpdate(key, parent);
|
|
533
|
+
}
|
|
534
|
+
else if (handler === true)
|
|
535
|
+
notify = this.onUpdate(key, parent);
|
|
536
|
+
if (!notify)
|
|
537
|
+
return;
|
|
538
|
+
const notate = () => {
|
|
539
|
+
UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
|
|
540
|
+
};
|
|
541
|
+
parent.waiting.add(notate);
|
|
542
|
+
parent.waiting.add(notify);
|
|
543
|
+
});
|
|
544
|
+
this.commit = () => {
|
|
545
|
+
this.active = true;
|
|
546
|
+
this.dependant.forEach(x => x.commit());
|
|
547
|
+
return this.release;
|
|
548
|
+
};
|
|
549
|
+
this.release = () => {
|
|
550
|
+
this.dependant.forEach(x => x.release());
|
|
551
|
+
release();
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
486
556
|
const UPDATE = new WeakMap();
|
|
557
|
+
const LISTEN = new WeakMap();
|
|
487
558
|
const CONTROL = Symbol("CONTROL");
|
|
488
559
|
function getUpdate(subject) {
|
|
489
560
|
return UPDATE.get(subject);
|
|
@@ -514,9 +585,9 @@ class Controller {
|
|
|
514
585
|
enumerable: false,
|
|
515
586
|
set: this.ref(key),
|
|
516
587
|
get() {
|
|
517
|
-
const
|
|
518
|
-
if (
|
|
519
|
-
|
|
588
|
+
const listen = LISTEN.get(this);
|
|
589
|
+
if (listen)
|
|
590
|
+
listen(key);
|
|
520
591
|
return state.get(key);
|
|
521
592
|
}
|
|
522
593
|
});
|
|
@@ -643,9 +714,10 @@ function apply(fn, label) {
|
|
|
643
714
|
get() {
|
|
644
715
|
if (!state.has(key) && suspense)
|
|
645
716
|
throw suspend(control, key);
|
|
717
|
+
const listen = LISTEN.get(this);
|
|
646
718
|
const local = this[LOCAL];
|
|
647
|
-
if (
|
|
648
|
-
|
|
719
|
+
if (listen)
|
|
720
|
+
listen(key);
|
|
649
721
|
return onGet
|
|
650
722
|
? onGet(local)
|
|
651
723
|
: state.get(key);
|
|
@@ -713,7 +785,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
713
785
|
});
|
|
714
786
|
}
|
|
715
787
|
|
|
716
|
-
const Oops$
|
|
788
|
+
const Oops$7 = issues({
|
|
717
789
|
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
718
790
|
});
|
|
719
791
|
function act(task) {
|
|
@@ -721,7 +793,7 @@ function act(task) {
|
|
|
721
793
|
let pending = false;
|
|
722
794
|
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
723
795
|
if (pending)
|
|
724
|
-
return Promise.reject(Oops$
|
|
796
|
+
return Promise.reject(Oops$7.DuplicatePending(key));
|
|
725
797
|
pending = true;
|
|
726
798
|
this.update(key);
|
|
727
799
|
try {
|
|
@@ -757,81 +829,6 @@ function ref(callback) {
|
|
|
757
829
|
});
|
|
758
830
|
}
|
|
759
831
|
|
|
760
|
-
const Oops$7 = issues({
|
|
761
|
-
NonOptional: (Parent, key) => `Property ${Parent}.${key} is marked as required.`,
|
|
762
|
-
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
763
|
-
Failed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
764
|
-
});
|
|
765
|
-
function put(factory, argument) {
|
|
766
|
-
return apply(function set(key) {
|
|
767
|
-
const { subject, state } = this;
|
|
768
|
-
const required = argument === true ||
|
|
769
|
-
argument === undefined;
|
|
770
|
-
let pending;
|
|
771
|
-
let error;
|
|
772
|
-
const init = () => {
|
|
773
|
-
const output = typeof factory == "function" ?
|
|
774
|
-
mayRetry(() => factory.call(subject, key, subject)) :
|
|
775
|
-
factory;
|
|
776
|
-
if (output instanceof Promise) {
|
|
777
|
-
pending = output
|
|
778
|
-
.catch(err => error = err)
|
|
779
|
-
.then(val => {
|
|
780
|
-
state.set(key, val);
|
|
781
|
-
return val;
|
|
782
|
-
})
|
|
783
|
-
.finally(() => {
|
|
784
|
-
pending = undefined;
|
|
785
|
-
this.update(key);
|
|
786
|
-
});
|
|
787
|
-
return;
|
|
788
|
-
}
|
|
789
|
-
state.set(key, output);
|
|
790
|
-
return output;
|
|
791
|
-
};
|
|
792
|
-
if (required)
|
|
793
|
-
try {
|
|
794
|
-
init();
|
|
795
|
-
}
|
|
796
|
-
catch (err) {
|
|
797
|
-
Oops$7.Failed(subject, key).warn();
|
|
798
|
-
throw err;
|
|
799
|
-
}
|
|
800
|
-
const suspend = () => {
|
|
801
|
-
if (required === false)
|
|
802
|
-
return undefined;
|
|
803
|
-
const issue = Oops$7.NotReady(subject, key);
|
|
804
|
-
Object.assign(pending, {
|
|
805
|
-
message: issue.message,
|
|
806
|
-
stack: issue.stack
|
|
807
|
-
});
|
|
808
|
-
throw pending;
|
|
809
|
-
};
|
|
810
|
-
const get = () => {
|
|
811
|
-
if (pending)
|
|
812
|
-
return suspend();
|
|
813
|
-
if (error)
|
|
814
|
-
throw error;
|
|
815
|
-
if (state.has(key))
|
|
816
|
-
return state.get(key);
|
|
817
|
-
const output = init();
|
|
818
|
-
return pending
|
|
819
|
-
? suspend()
|
|
820
|
-
: output;
|
|
821
|
-
};
|
|
822
|
-
const set = typeof argument == "function"
|
|
823
|
-
? createValueEffect(argument)
|
|
824
|
-
: (value) => {
|
|
825
|
-
if (value === undefined && required)
|
|
826
|
-
throw Oops$7.NonOptional(subject, key);
|
|
827
|
-
};
|
|
828
|
-
return {
|
|
829
|
-
set,
|
|
830
|
-
get
|
|
831
|
-
};
|
|
832
|
-
});
|
|
833
|
-
}
|
|
834
|
-
|
|
835
832
|
function set(value, argument) {
|
|
836
833
|
if (!(1 in arguments)) {
|
|
837
834
|
argument = value;
|
|
@@ -995,31 +992,77 @@ function createProxy(emit, watch) {
|
|
|
995
992
|
const Parent = new WeakMap();
|
|
996
993
|
const Oops$6 = issues({
|
|
997
994
|
BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
|
|
995
|
+
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
998
996
|
});
|
|
999
997
|
function use$1(input, argument) {
|
|
1000
998
|
return apply(function use(key) {
|
|
1001
999
|
const { state, subject } = this;
|
|
1000
|
+
const required = argument !== false;
|
|
1001
|
+
let pending;
|
|
1002
|
+
let error;
|
|
1003
|
+
let get = (_local) => state.get(key);
|
|
1002
1004
|
if (typeof input === "function")
|
|
1003
|
-
input =
|
|
1005
|
+
input = /^[A-Z]/.test(input.name)
|
|
1006
|
+
? new input() : input;
|
|
1004
1007
|
else if (input && typeof input !== "object")
|
|
1005
1008
|
throw Oops$6.BadArgument(typeof input);
|
|
1006
1009
|
if (input instanceof Map || input instanceof Set)
|
|
1007
1010
|
return keyed(this, key, input);
|
|
1008
|
-
|
|
1011
|
+
const onUpdate = (next) => {
|
|
1009
1012
|
state.set(key, next);
|
|
1010
1013
|
if (next) {
|
|
1014
|
+
get = getRecursive(key, this);
|
|
1011
1015
|
Parent.set(next, subject);
|
|
1012
1016
|
ensure(next);
|
|
1013
1017
|
}
|
|
1014
1018
|
if (typeof argument == "function")
|
|
1015
1019
|
argument(next);
|
|
1016
1020
|
return true;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1021
|
+
};
|
|
1022
|
+
const suspend = () => {
|
|
1023
|
+
if (required === false)
|
|
1024
|
+
return;
|
|
1025
|
+
const issue = Oops$6.NotReady(subject, key);
|
|
1026
|
+
Object.assign(pending, {
|
|
1027
|
+
message: issue.message,
|
|
1028
|
+
stack: issue.stack
|
|
1029
|
+
});
|
|
1030
|
+
throw pending;
|
|
1031
|
+
};
|
|
1032
|
+
const initialize = () => {
|
|
1033
|
+
const output = typeof input == "function" ?
|
|
1034
|
+
mayRetry(() => input.call(subject, subject)) :
|
|
1035
|
+
input;
|
|
1036
|
+
if (output instanceof Promise) {
|
|
1037
|
+
pending = output
|
|
1038
|
+
.catch(err => error = err)
|
|
1039
|
+
.then(val => {
|
|
1040
|
+
onUpdate(val);
|
|
1041
|
+
return val;
|
|
1042
|
+
})
|
|
1043
|
+
.finally(() => {
|
|
1044
|
+
pending = undefined;
|
|
1045
|
+
this.update(key);
|
|
1046
|
+
});
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
onUpdate(output);
|
|
1050
|
+
};
|
|
1051
|
+
if (input !== undefined && required)
|
|
1052
|
+
initialize();
|
|
1020
1053
|
return {
|
|
1021
1054
|
set: onUpdate,
|
|
1022
|
-
|
|
1055
|
+
get(local) {
|
|
1056
|
+
if (pending)
|
|
1057
|
+
return suspend();
|
|
1058
|
+
if (error)
|
|
1059
|
+
throw error;
|
|
1060
|
+
if (!state.has(key))
|
|
1061
|
+
initialize();
|
|
1062
|
+
if (pending)
|
|
1063
|
+
return suspend();
|
|
1064
|
+
return get(local);
|
|
1065
|
+
}
|
|
1023
1066
|
};
|
|
1024
1067
|
});
|
|
1025
1068
|
}
|
|
@@ -1479,7 +1522,6 @@ exports.apply = apply;
|
|
|
1479
1522
|
exports["default"] = MVC;
|
|
1480
1523
|
exports.get = get;
|
|
1481
1524
|
exports.has = has;
|
|
1482
|
-
exports.put = put;
|
|
1483
1525
|
exports.ref = ref;
|
|
1484
1526
|
exports.set = set;
|
|
1485
1527
|
exports.tap = tap;
|