@expressive/mvc 1.0.0-beta.25 → 1.0.0-beta.29
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 +356 -334
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +356 -334
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/types/model.d.ts +38 -14
- package/types/types.d.ts +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) {
|
|
@@ -92,14 +92,34 @@ class Subscriber {
|
|
|
92
92
|
constructor(parent, onUpdate) {
|
|
93
93
|
this.onUpdate = onUpdate;
|
|
94
94
|
this.active = false;
|
|
95
|
-
this.
|
|
95
|
+
this.handle = {};
|
|
96
96
|
this.dependant = new Set();
|
|
97
|
+
this.debug = () => {
|
|
98
|
+
const update = [];
|
|
99
|
+
this.notify = keys => {
|
|
100
|
+
update.splice(0, update.length, ...keys.filter(k => k in this.handle));
|
|
101
|
+
};
|
|
102
|
+
return update;
|
|
103
|
+
};
|
|
104
|
+
this.listen = (key, from) => {
|
|
105
|
+
const handler = this.handle[key];
|
|
106
|
+
if (!handler)
|
|
107
|
+
return;
|
|
108
|
+
if (typeof handler == "function")
|
|
109
|
+
handler();
|
|
110
|
+
const notify = this.onUpdate(key, from);
|
|
111
|
+
if (notify)
|
|
112
|
+
from.waiting.add(notify);
|
|
113
|
+
if (this.notify)
|
|
114
|
+
from.waiting.add(this.notify);
|
|
115
|
+
};
|
|
97
116
|
if (!(parent instanceof Controller))
|
|
98
117
|
parent = manage(parent);
|
|
99
118
|
this.parent = parent;
|
|
100
119
|
this.source = parent.subject;
|
|
101
120
|
this.proxy = create(parent.subject);
|
|
102
121
|
define(this.proxy, LOCAL, this);
|
|
122
|
+
defineLazy(this.proxy, UPDATE, this.debug);
|
|
103
123
|
for (const key in parent.state)
|
|
104
124
|
this.spy(key);
|
|
105
125
|
}
|
|
@@ -119,43 +139,47 @@ class Subscriber {
|
|
|
119
139
|
enumerable: true
|
|
120
140
|
});
|
|
121
141
|
}
|
|
122
|
-
follow(key,
|
|
123
|
-
this.
|
|
142
|
+
follow(key, callback) {
|
|
143
|
+
this.handle[key] = callback || true;
|
|
124
144
|
}
|
|
125
145
|
commit() {
|
|
126
|
-
const
|
|
127
|
-
const onDone = parent.addListener(follows);
|
|
146
|
+
const onDone = this.parent.addListener(this.listen);
|
|
128
147
|
this.active = true;
|
|
129
|
-
dependant.forEach(x => x.commit());
|
|
148
|
+
this.dependant.forEach(x => x.commit());
|
|
130
149
|
return this.release = () => {
|
|
131
|
-
dependant.forEach(x => x.release());
|
|
150
|
+
this.dependant.forEach(x => x.release());
|
|
132
151
|
onDone();
|
|
133
152
|
};
|
|
134
153
|
}
|
|
135
154
|
}
|
|
136
155
|
|
|
137
|
-
const Oops$
|
|
156
|
+
const Oops$7 = issues({
|
|
138
157
|
ComputeFailed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
139
158
|
ComputedEarly: (property) => `Note: Computed values don't run until accessed, except when subscribed to. '${property}' getter may have run earlier than intended.`
|
|
140
159
|
});
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
const
|
|
160
|
+
const INIT = new WeakSet();
|
|
161
|
+
const INFO = new WeakMap();
|
|
162
|
+
const USED = new WeakMap();
|
|
163
|
+
const KEYS = new WeakMap();
|
|
145
164
|
function prepare(parent, key, source, setter, getter) {
|
|
146
165
|
let sub;
|
|
147
166
|
const { state, subject } = parent;
|
|
148
167
|
const info = { key, parent, priority: 1 };
|
|
168
|
+
let register = USED.get(parent);
|
|
169
|
+
if (!register) {
|
|
170
|
+
register = new Map();
|
|
171
|
+
USED.set(parent, register);
|
|
172
|
+
}
|
|
173
|
+
register.set(key, info);
|
|
149
174
|
const current = getter
|
|
150
175
|
? () => getter.call(subject, state[key], key)
|
|
151
176
|
: () => state[key];
|
|
152
|
-
const prioritize = register(parent, key, info);
|
|
153
177
|
function compute(initial) {
|
|
154
178
|
try {
|
|
155
179
|
return setter.call(sub.proxy, sub.proxy);
|
|
156
180
|
}
|
|
157
181
|
catch (err) {
|
|
158
|
-
Oops$
|
|
182
|
+
Oops$7.ComputeFailed(subject, key, !!initial).warn();
|
|
159
183
|
throw err;
|
|
160
184
|
}
|
|
161
185
|
}
|
|
@@ -174,8 +198,19 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
174
198
|
}
|
|
175
199
|
}
|
|
176
200
|
}
|
|
201
|
+
function defer(_key, from) {
|
|
202
|
+
let pending = KEYS.get(from);
|
|
203
|
+
if (!pending)
|
|
204
|
+
KEYS.set(from, pending = []);
|
|
205
|
+
if (info.parent !== from)
|
|
206
|
+
update();
|
|
207
|
+
else {
|
|
208
|
+
const after = pending.findIndex(peer => (info.priority > INFO.get(peer).priority));
|
|
209
|
+
pending.splice(after + 1, 0, update);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
177
212
|
function create(early) {
|
|
178
|
-
sub = new Subscriber(source(),
|
|
213
|
+
sub = new Subscriber(source(), defer);
|
|
179
214
|
defineProperty(state, key, {
|
|
180
215
|
value: undefined,
|
|
181
216
|
writable: true
|
|
@@ -190,21 +225,24 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
190
225
|
}
|
|
191
226
|
catch (e) {
|
|
192
227
|
if (early)
|
|
193
|
-
Oops$
|
|
228
|
+
Oops$7.ComputedEarly(key).warn();
|
|
194
229
|
throw e;
|
|
195
230
|
}
|
|
196
231
|
finally {
|
|
197
232
|
sub.commit();
|
|
198
|
-
for (const key in sub.
|
|
199
|
-
|
|
233
|
+
for (const key in sub.handle) {
|
|
234
|
+
const peer = register.get(key);
|
|
235
|
+
if (peer && peer.priority >= info.priority)
|
|
236
|
+
info.priority = peer.priority + 1;
|
|
237
|
+
}
|
|
200
238
|
}
|
|
201
239
|
return current();
|
|
202
240
|
}
|
|
203
241
|
setAlias(update, `try ${key}`);
|
|
204
242
|
setAlias(create, `new ${key}`);
|
|
205
243
|
setAlias(setter, `run ${key}`);
|
|
206
|
-
|
|
207
|
-
|
|
244
|
+
INIT.add(create);
|
|
245
|
+
INFO.set(update, info);
|
|
208
246
|
for (const on of [state, subject])
|
|
209
247
|
defineProperty(on, key, {
|
|
210
248
|
get: create,
|
|
@@ -212,53 +250,27 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
212
250
|
enumerable: true
|
|
213
251
|
});
|
|
214
252
|
}
|
|
215
|
-
function register(on, key, info) {
|
|
216
|
-
let register = ComputedUsed.get(on);
|
|
217
|
-
if (!register)
|
|
218
|
-
ComputedUsed.set(on, register = new Map());
|
|
219
|
-
register.set(key, info);
|
|
220
|
-
return (key) => {
|
|
221
|
-
const peer = register.get(key);
|
|
222
|
-
if (peer && peer.priority >= info.priority)
|
|
223
|
-
info.priority = peer.priority + 1;
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
253
|
function ensure(on, keys) {
|
|
227
254
|
for (const key of keys) {
|
|
228
255
|
const desc = getOwnPropertyDescriptor(on.subject, key);
|
|
229
256
|
const getter = desc && desc.get;
|
|
230
|
-
if (
|
|
257
|
+
if (INIT.has(getter))
|
|
231
258
|
getter(true);
|
|
232
259
|
}
|
|
233
260
|
}
|
|
234
|
-
function capture(on, request) {
|
|
235
|
-
const compute = ComputedInfo.get(request);
|
|
236
|
-
const callback = request;
|
|
237
|
-
if (!compute)
|
|
238
|
-
return;
|
|
239
|
-
let pending = ComputedKeys.get(on);
|
|
240
|
-
if (!pending)
|
|
241
|
-
ComputedKeys.set(on, pending = []);
|
|
242
|
-
if (compute.parent !== on)
|
|
243
|
-
callback();
|
|
244
|
-
else {
|
|
245
|
-
const queue = pending.findIndex(peer => compute.priority > ComputedInfo.get(peer).priority);
|
|
246
|
-
pending.splice(queue + 1, 0, callback);
|
|
247
|
-
}
|
|
248
|
-
return true;
|
|
249
|
-
}
|
|
250
261
|
function flush(on) {
|
|
251
262
|
const handled = on.frame;
|
|
252
|
-
|
|
253
|
-
if (pending)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
263
|
+
const pending = KEYS.get(on);
|
|
264
|
+
if (!pending)
|
|
265
|
+
return;
|
|
266
|
+
while (pending.length) {
|
|
267
|
+
const why = [...handled];
|
|
268
|
+
const compute = pending.shift();
|
|
269
|
+
const { key } = INFO.get(compute);
|
|
270
|
+
if (!handled.has(key))
|
|
271
|
+
compute(why);
|
|
272
|
+
}
|
|
273
|
+
KEYS.delete(on);
|
|
262
274
|
}
|
|
263
275
|
|
|
264
276
|
const Lifecycle = {
|
|
@@ -309,6 +321,7 @@ function eventsFor(prefix) {
|
|
|
309
321
|
}
|
|
310
322
|
|
|
311
323
|
const CONTROL = Symbol("control");
|
|
324
|
+
const UPDATE = Symbol("update");
|
|
312
325
|
const LOCAL = Symbol("local");
|
|
313
326
|
const STATE = Symbol("state");
|
|
314
327
|
function manage(src) {
|
|
@@ -337,8 +350,8 @@ class Controller {
|
|
|
337
350
|
this.subject = subject;
|
|
338
351
|
this.state = {};
|
|
339
352
|
this.frame = new Set();
|
|
340
|
-
this.
|
|
341
|
-
this.
|
|
353
|
+
this.waiting = new Set();
|
|
354
|
+
this.followers = new Set();
|
|
342
355
|
}
|
|
343
356
|
static setup(onto) {
|
|
344
357
|
const control = new this(onto);
|
|
@@ -404,18 +417,12 @@ class Controller {
|
|
|
404
417
|
this.update(key, value);
|
|
405
418
|
};
|
|
406
419
|
}
|
|
407
|
-
addListener(
|
|
408
|
-
this.
|
|
420
|
+
addListener(listener) {
|
|
421
|
+
this.followers.add(listener);
|
|
409
422
|
return () => {
|
|
410
|
-
this.
|
|
423
|
+
this.followers.delete(listener);
|
|
411
424
|
};
|
|
412
425
|
}
|
|
413
|
-
include(to) {
|
|
414
|
-
if (capture(this, to))
|
|
415
|
-
return;
|
|
416
|
-
else
|
|
417
|
-
this.waiting.push(to);
|
|
418
|
-
}
|
|
419
426
|
update(key, value) {
|
|
420
427
|
if (1 in arguments)
|
|
421
428
|
this.state[key] = value;
|
|
@@ -424,15 +431,22 @@ class Controller {
|
|
|
424
431
|
if (!this.frame.size)
|
|
425
432
|
setTimeout(() => this.emit(), 0);
|
|
426
433
|
this.frame.add(key);
|
|
427
|
-
for (const subscription of this.
|
|
428
|
-
|
|
429
|
-
|
|
434
|
+
for (const subscription of this.followers) {
|
|
435
|
+
const notify = subscription(key, this);
|
|
436
|
+
if (notify)
|
|
437
|
+
this.waiting.add(notify);
|
|
438
|
+
}
|
|
430
439
|
}
|
|
431
440
|
emit() {
|
|
432
441
|
flush(this);
|
|
433
|
-
const keys =
|
|
434
|
-
const handle = new Set(this.waiting
|
|
442
|
+
const keys = Object.freeze([...this.frame]);
|
|
443
|
+
const handle = new Set(this.waiting);
|
|
444
|
+
this.waiting.clear();
|
|
435
445
|
this.frame.clear();
|
|
446
|
+
defineProperty(this.subject, UPDATE, {
|
|
447
|
+
configurable: true,
|
|
448
|
+
value: keys
|
|
449
|
+
});
|
|
436
450
|
handle.forEach(callback => {
|
|
437
451
|
try {
|
|
438
452
|
callback(keys);
|
|
@@ -444,104 +458,52 @@ class Controller {
|
|
|
444
458
|
function keys(from, using) {
|
|
445
459
|
if (typeof using == "string")
|
|
446
460
|
return [using];
|
|
447
|
-
if (typeof using == "object")
|
|
448
|
-
|
|
461
|
+
if (typeof using == "object") {
|
|
462
|
+
using = Array.from(using);
|
|
463
|
+
if (using.length === 0)
|
|
464
|
+
using = undefined;
|
|
465
|
+
else
|
|
466
|
+
return using;
|
|
467
|
+
}
|
|
449
468
|
return from.select(using);
|
|
450
469
|
}
|
|
451
470
|
|
|
452
|
-
function child(
|
|
471
|
+
function child(source, name) {
|
|
453
472
|
return apply(function child(key) {
|
|
454
|
-
const
|
|
455
|
-
const
|
|
473
|
+
const context = new WeakMap();
|
|
474
|
+
const current = source.call(this, key);
|
|
456
475
|
function subscribe(sub) {
|
|
457
476
|
let child;
|
|
458
477
|
function start() {
|
|
459
|
-
const instance =
|
|
478
|
+
const instance = current();
|
|
460
479
|
if (instance) {
|
|
461
480
|
child = new Subscriber(instance, sub.onUpdate);
|
|
462
481
|
if (sub.active)
|
|
463
482
|
child.commit();
|
|
464
483
|
sub.dependant.add(child);
|
|
465
|
-
|
|
484
|
+
context.set(sub, child.proxy);
|
|
466
485
|
}
|
|
467
486
|
}
|
|
468
|
-
function
|
|
487
|
+
function restart() {
|
|
469
488
|
if (child) {
|
|
470
489
|
child.release();
|
|
471
490
|
sub.dependant.delete(child);
|
|
472
|
-
|
|
491
|
+
context.set(sub, undefined);
|
|
473
492
|
child = undefined;
|
|
474
493
|
}
|
|
475
494
|
start();
|
|
476
|
-
sub.onUpdate();
|
|
477
495
|
}
|
|
478
496
|
start();
|
|
479
|
-
sub.follow(key,
|
|
497
|
+
sub.follow(key, restart);
|
|
480
498
|
}
|
|
481
499
|
return (local) => {
|
|
482
500
|
if (!local)
|
|
483
|
-
return
|
|
484
|
-
if (!
|
|
501
|
+
return current();
|
|
502
|
+
if (!context.has(local))
|
|
485
503
|
subscribe(local);
|
|
486
|
-
return
|
|
504
|
+
return context.get(local);
|
|
487
505
|
};
|
|
488
|
-
}, name ||
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
const Oops$7 = issues({
|
|
492
|
-
HasPropertyUndefined: (control, property) => `${control}.${property} is marked as required for this render.`
|
|
493
|
-
});
|
|
494
|
-
function use$1(init) {
|
|
495
|
-
const [state, update] = useState(() => [
|
|
496
|
-
init(() => update(state.concat()))
|
|
497
|
-
]);
|
|
498
|
-
return state[0];
|
|
499
|
-
}
|
|
500
|
-
function useLazy(Type, callback) {
|
|
501
|
-
const instance = useMemo(() => {
|
|
502
|
-
const instance = Type.create();
|
|
503
|
-
if (callback)
|
|
504
|
-
callback(instance);
|
|
505
|
-
return instance;
|
|
506
|
-
}, []);
|
|
507
|
-
useLayoutEffect(() => () => instance.destroy(), []);
|
|
508
|
-
return instance;
|
|
509
|
-
}
|
|
510
|
-
function useWatcher(target, focus, expected) {
|
|
511
|
-
const hook = use$1(refresh => {
|
|
512
|
-
const sub = new Subscriber(target, refresh);
|
|
513
|
-
if (focus) {
|
|
514
|
-
const src = sub.proxy;
|
|
515
|
-
const key = keys(sub.parent, focus)[0];
|
|
516
|
-
defineProperty(sub, "proxy", {
|
|
517
|
-
get() {
|
|
518
|
-
if (src[key] === undefined && expected)
|
|
519
|
-
throw Oops$7.HasPropertyUndefined(target, key);
|
|
520
|
-
return src[key];
|
|
521
|
-
}
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
return sub;
|
|
525
|
-
});
|
|
526
|
-
useLayoutEffect(() => hook.commit(), []);
|
|
527
|
-
return hook.proxy;
|
|
528
|
-
}
|
|
529
|
-
function useModel(Type, callback) {
|
|
530
|
-
const hook = use$1(refresh => {
|
|
531
|
-
const instance = new Type();
|
|
532
|
-
const control = manage(instance);
|
|
533
|
-
const sub = new Subscriber(control, refresh);
|
|
534
|
-
const release = control.addListener({
|
|
535
|
-
[Lifecycle.WILL_UNMOUNT]() {
|
|
536
|
-
instance.destroy();
|
|
537
|
-
release();
|
|
538
|
-
}
|
|
539
|
-
});
|
|
540
|
-
if (callback)
|
|
541
|
-
callback(instance);
|
|
542
|
-
return sub;
|
|
543
|
-
});
|
|
544
|
-
return hook.proxy;
|
|
506
|
+
}, name || source.name);
|
|
545
507
|
}
|
|
546
508
|
|
|
547
509
|
const Oops$6 = issues({
|
|
@@ -594,6 +556,219 @@ function getPending(subject) {
|
|
|
594
556
|
return pending;
|
|
595
557
|
}
|
|
596
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
|
+
setAlias(invoke, `run ${key}`);
|
|
601
|
+
defineProperty(invoke, "active", {
|
|
602
|
+
get: () => pending
|
|
603
|
+
});
|
|
604
|
+
return {
|
|
605
|
+
value: invoke,
|
|
606
|
+
writable: false
|
|
607
|
+
};
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
function from(source, setter, getter) {
|
|
611
|
+
return apply(function from(key) {
|
|
612
|
+
const { subject } = this;
|
|
613
|
+
let getSource;
|
|
614
|
+
// Easy mistake, using a peer, will always be unresolved.
|
|
615
|
+
if (typeof source == "symbol")
|
|
616
|
+
throw Oops$5.PeerNotAllowed(subject, key);
|
|
617
|
+
// replace source controller in-case different
|
|
618
|
+
if (typeof source == "object")
|
|
619
|
+
getSource = () => manage(source);
|
|
620
|
+
// specifically an arrow function (getter factory)
|
|
621
|
+
else if (!source.prototype) {
|
|
622
|
+
setter = source.call(subject, key);
|
|
623
|
+
getSource = () => this;
|
|
624
|
+
}
|
|
625
|
+
// is a peer Model (constructor)
|
|
626
|
+
else if (Model.isTypeof(source))
|
|
627
|
+
getSource = pendingAccess(subject, source, key, true);
|
|
628
|
+
// Regular function is to ambiguous so not allowed.
|
|
629
|
+
else
|
|
630
|
+
throw Oops$5.BadComputedSource(subject, key, source);
|
|
631
|
+
prepare(this, key, getSource, setter, getter);
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
const Oops$4 = issues({
|
|
636
|
+
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
637
|
+
});
|
|
638
|
+
function pending(source, compute) {
|
|
639
|
+
return (source === undefined ?
|
|
640
|
+
suspendForValue() :
|
|
641
|
+
typeof source == "function" && !source.prototype ?
|
|
642
|
+
suspendForAsync(source) :
|
|
643
|
+
suspendForComputed(source, compute));
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Get value, suspend instead if undefined.
|
|
647
|
+
*
|
|
648
|
+
* Throws suspense promise also interpretable as an error.
|
|
649
|
+
* React could handle it but other contexts probably not.
|
|
650
|
+
*/
|
|
651
|
+
function pendingValue(via, key) {
|
|
652
|
+
const value = via.state[key];
|
|
653
|
+
if (value === undefined)
|
|
654
|
+
throw suspend(via, key);
|
|
655
|
+
return value;
|
|
656
|
+
}
|
|
657
|
+
function suspend(source, key) {
|
|
658
|
+
const error = Oops$4.ValueNotReady(source.subject, key);
|
|
659
|
+
const promise = new Promise(resolve => {
|
|
660
|
+
const release = source.addListener(forKey => {
|
|
661
|
+
if (forKey == key)
|
|
662
|
+
return () => {
|
|
663
|
+
if (source.state[key] !== undefined) {
|
|
664
|
+
release();
|
|
665
|
+
resolve();
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
});
|
|
669
|
+
});
|
|
670
|
+
return Object.assign(promise, {
|
|
671
|
+
toString: () => String(error),
|
|
672
|
+
name: "Suspense",
|
|
673
|
+
message: error.message,
|
|
674
|
+
stack: error.stack
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
function suspendForComputed(source, compute) {
|
|
678
|
+
function getter(_value, key) {
|
|
679
|
+
return pendingValue(manage(this), key);
|
|
680
|
+
}
|
|
681
|
+
return from(source, compute, getter);
|
|
682
|
+
}
|
|
683
|
+
function suspendForValue() {
|
|
684
|
+
return apply(function pending(key) {
|
|
685
|
+
this.state[key] = undefined;
|
|
686
|
+
return {
|
|
687
|
+
set: this.setter(key),
|
|
688
|
+
get: () => pendingValue(this, key)
|
|
689
|
+
};
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
function suspendForAsync(source) {
|
|
693
|
+
return apply(function suspense(key) {
|
|
694
|
+
const subject = this.subject;
|
|
695
|
+
let waiting = true;
|
|
696
|
+
let value;
|
|
697
|
+
let error;
|
|
698
|
+
return () => {
|
|
699
|
+
if (error)
|
|
700
|
+
throw error;
|
|
701
|
+
if (!waiting)
|
|
702
|
+
return value;
|
|
703
|
+
const issue = Oops$4.ValueNotReady(subject, key);
|
|
704
|
+
let suspend = source
|
|
705
|
+
.call(subject, key)
|
|
706
|
+
.catch(err => error = err)
|
|
707
|
+
.then(out => value = out)
|
|
708
|
+
.finally(() => waiting = false);
|
|
709
|
+
throw Object.assign(suspend, {
|
|
710
|
+
message: issue.message,
|
|
711
|
+
stack: issue.stack
|
|
712
|
+
});
|
|
713
|
+
};
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function use$1(init) {
|
|
718
|
+
const [state, update] = useState(() => [
|
|
719
|
+
init(() => update(state.concat()))
|
|
720
|
+
]);
|
|
721
|
+
return state[0];
|
|
722
|
+
}
|
|
723
|
+
function useLazy(Type, callback) {
|
|
724
|
+
const instance = useMemo(() => {
|
|
725
|
+
const instance = Type.create();
|
|
726
|
+
if (callback)
|
|
727
|
+
callback(instance);
|
|
728
|
+
return instance;
|
|
729
|
+
}, []);
|
|
730
|
+
useLayoutEffect(() => () => instance.destroy(), []);
|
|
731
|
+
return instance;
|
|
732
|
+
}
|
|
733
|
+
function useWatcher(target, focus, expected) {
|
|
734
|
+
const hook = use$1(refresh => {
|
|
735
|
+
const sub = new Subscriber(target, () => refresh);
|
|
736
|
+
if (focus) {
|
|
737
|
+
const source = sub.proxy;
|
|
738
|
+
const key = keys(sub.parent, focus)[0];
|
|
739
|
+
defineProperty(sub, "proxy", {
|
|
740
|
+
get() {
|
|
741
|
+
const value = source[key];
|
|
742
|
+
if (value === undefined && expected)
|
|
743
|
+
throw suspend(sub.parent, key);
|
|
744
|
+
return value;
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
return sub;
|
|
749
|
+
});
|
|
750
|
+
useLayoutEffect(() => hook.commit(), []);
|
|
751
|
+
return hook.proxy;
|
|
752
|
+
}
|
|
753
|
+
function useModel(Type, callback) {
|
|
754
|
+
const hook = use$1(refresh => {
|
|
755
|
+
const instance = new Type();
|
|
756
|
+
const control = manage(instance);
|
|
757
|
+
const sub = new Subscriber(control, () => refresh);
|
|
758
|
+
const release = control.addListener((key) => {
|
|
759
|
+
if (key == Lifecycle.WILL_UNMOUNT)
|
|
760
|
+
return () => {
|
|
761
|
+
instance.destroy();
|
|
762
|
+
release();
|
|
763
|
+
};
|
|
764
|
+
});
|
|
765
|
+
if (callback)
|
|
766
|
+
callback(instance);
|
|
767
|
+
return sub;
|
|
768
|
+
});
|
|
769
|
+
return hook.proxy;
|
|
770
|
+
}
|
|
771
|
+
|
|
597
772
|
class Lookup {
|
|
598
773
|
constructor() {
|
|
599
774
|
this.table = new Map();
|
|
@@ -649,7 +824,7 @@ class Lookup {
|
|
|
649
824
|
}
|
|
650
825
|
}
|
|
651
826
|
|
|
652
|
-
const Oops$
|
|
827
|
+
const Oops$3 = issues({
|
|
653
828
|
NoProviderType: () => `Provider 'of' prop must be Model, typeof Model or a collection of them.`,
|
|
654
829
|
NothingInContext: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`,
|
|
655
830
|
BadConsumerProps: () => `Provider expects either a render function, 'get' or 'has' props.`
|
|
@@ -659,7 +834,7 @@ const useLookup = () => useContext(LookupContext);
|
|
|
659
834
|
function useFromContext(Type, strict) {
|
|
660
835
|
const instance = useLookup().get(Type);
|
|
661
836
|
if (!instance && strict)
|
|
662
|
-
throw Oops$
|
|
837
|
+
throw Oops$3.NothingInContext(Type.name);
|
|
663
838
|
return instance;
|
|
664
839
|
}
|
|
665
840
|
function Consumer(props) {
|
|
@@ -670,13 +845,13 @@ function Consumer(props) {
|
|
|
670
845
|
if (typeof callback == "function")
|
|
671
846
|
callback(Control.get(!!has));
|
|
672
847
|
else
|
|
673
|
-
throw Oops$
|
|
848
|
+
throw Oops$3.BadConsumerProps();
|
|
674
849
|
return null;
|
|
675
850
|
}
|
|
676
851
|
function useNewContext(from, inject) {
|
|
677
852
|
return useMemo(() => {
|
|
678
853
|
if (!inject)
|
|
679
|
-
throw Oops$
|
|
854
|
+
throw Oops$3.NoProviderType();
|
|
680
855
|
const context = from.push(inject);
|
|
681
856
|
for (const instance of context.local)
|
|
682
857
|
for (const apply of getPending(instance))
|
|
@@ -701,7 +876,7 @@ function RenderFunction(props) {
|
|
|
701
876
|
const hook = use$1(refresh => {
|
|
702
877
|
const targets = props.context.local;
|
|
703
878
|
if (targets.length == 1)
|
|
704
|
-
return new Subscriber(targets[0], refresh);
|
|
879
|
+
return new Subscriber(targets[0], () => refresh);
|
|
705
880
|
return {};
|
|
706
881
|
});
|
|
707
882
|
if (hook.commit)
|
|
@@ -719,7 +894,7 @@ function Provider(props) {
|
|
|
719
894
|
: render);
|
|
720
895
|
}
|
|
721
896
|
|
|
722
|
-
const Oops$
|
|
897
|
+
const Oops$2 = issues({
|
|
723
898
|
StrictUpdate: (expected) => `Strict update() did ${expected ? "not " : ""}find pending updates.`,
|
|
724
899
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
725
900
|
});
|
|
@@ -732,7 +907,7 @@ class Model {
|
|
|
732
907
|
define(this, "set", this);
|
|
733
908
|
defer(control, "on");
|
|
734
909
|
defer(control, "effect");
|
|
735
|
-
control.
|
|
910
|
+
control.waiting.add(() => {
|
|
736
911
|
delete this.on;
|
|
737
912
|
delete this.effect;
|
|
738
913
|
});
|
|
@@ -744,7 +919,7 @@ class Model {
|
|
|
744
919
|
}
|
|
745
920
|
tag(id) {
|
|
746
921
|
const hook = use$1(refresh => {
|
|
747
|
-
return new Subscriber(this, refresh);
|
|
922
|
+
return new Subscriber(this, () => refresh);
|
|
748
923
|
});
|
|
749
924
|
useElementLifecycle(hook, id || 0);
|
|
750
925
|
return hook.proxy;
|
|
@@ -753,29 +928,27 @@ class Model {
|
|
|
753
928
|
const hook = use$1(refresh => {
|
|
754
929
|
if (callback)
|
|
755
930
|
callback(this);
|
|
756
|
-
return new Subscriber(this, refresh);
|
|
931
|
+
return new Subscriber(this, () => refresh);
|
|
757
932
|
});
|
|
758
933
|
useComponentLifecycle(hook);
|
|
759
934
|
return hook.proxy;
|
|
760
935
|
}
|
|
761
936
|
on(subset, handler, squash, once) {
|
|
762
937
|
const control = manage(this);
|
|
763
|
-
const
|
|
764
|
-
const batch = {};
|
|
765
|
-
const remove = control.addListener(batch);
|
|
938
|
+
const request = keys(control, subset);
|
|
766
939
|
const callback = squash
|
|
767
940
|
? handler.bind(this)
|
|
768
|
-
:
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
}
|
|
773
|
-
const handle = once
|
|
774
|
-
? (k) => { remove(); callback(k); }
|
|
941
|
+
: frame => frame
|
|
942
|
+
.filter(k => request.includes(k))
|
|
943
|
+
.forEach(k => handler.call(this, control.state[k], k));
|
|
944
|
+
const trigger = once
|
|
945
|
+
? frame => { remove(); callback(frame); }
|
|
775
946
|
: callback;
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
947
|
+
ensure(control, request);
|
|
948
|
+
const remove = control.addListener(key => {
|
|
949
|
+
if (request.includes(key))
|
|
950
|
+
return trigger;
|
|
951
|
+
});
|
|
779
952
|
return remove;
|
|
780
953
|
}
|
|
781
954
|
once(select, callback, squash) {
|
|
@@ -796,7 +969,7 @@ class Model {
|
|
|
796
969
|
return this.on(select, invoke, true);
|
|
797
970
|
}
|
|
798
971
|
else {
|
|
799
|
-
const sub = new Subscriber(control, invoke);
|
|
972
|
+
const sub = new Subscriber(control, () => invoke);
|
|
800
973
|
target = sub.proxy;
|
|
801
974
|
invoke();
|
|
802
975
|
return sub.commit();
|
|
@@ -820,7 +993,7 @@ class Model {
|
|
|
820
993
|
arg = select(this, arg);
|
|
821
994
|
if (typeof arg == "boolean") {
|
|
822
995
|
if (!control.pending === arg)
|
|
823
|
-
return Promise.reject(Oops$
|
|
996
|
+
return Promise.reject(Oops$2.StrictUpdate(arg));
|
|
824
997
|
}
|
|
825
998
|
else if (arg) {
|
|
826
999
|
control.update(arg);
|
|
@@ -837,11 +1010,11 @@ class Model {
|
|
|
837
1010
|
then(callback) {
|
|
838
1011
|
if (callback)
|
|
839
1012
|
if (control.pending)
|
|
840
|
-
control.
|
|
1013
|
+
control.waiting.add(callback);
|
|
841
1014
|
else
|
|
842
1015
|
callback(false);
|
|
843
1016
|
else
|
|
844
|
-
throw Oops$
|
|
1017
|
+
throw Oops$2.NoChaining();
|
|
845
1018
|
}
|
|
846
1019
|
};
|
|
847
1020
|
}
|
|
@@ -905,6 +1078,7 @@ class Model {
|
|
|
905
1078
|
Model.CONTROL = CONTROL;
|
|
906
1079
|
Model.STATE = STATE;
|
|
907
1080
|
Model.LOCAL = LOCAL;
|
|
1081
|
+
Model.WHY = UPDATE;
|
|
908
1082
|
defineLazy(Model, CONTROL, function () {
|
|
909
1083
|
return new Controller(this).start();
|
|
910
1084
|
});
|
|
@@ -913,7 +1087,7 @@ function defer(on, method) {
|
|
|
913
1087
|
const real = subject[method];
|
|
914
1088
|
subject[method] = (...args) => {
|
|
915
1089
|
let done;
|
|
916
|
-
waiting.
|
|
1090
|
+
waiting.add(() => {
|
|
917
1091
|
done = real.apply(subject, args);
|
|
918
1092
|
});
|
|
919
1093
|
return () => done();
|
|
@@ -921,7 +1095,7 @@ function defer(on, method) {
|
|
|
921
1095
|
}
|
|
922
1096
|
|
|
923
1097
|
const Parent = new WeakMap();
|
|
924
|
-
const Oops$
|
|
1098
|
+
const Oops$1 = issues({
|
|
925
1099
|
ParentRequired: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
|
|
926
1100
|
UnexpectedParent: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
927
1101
|
UndefinedNotAllowed: (key) => `Child property ${key} may not be undefined.`,
|
|
@@ -946,7 +1120,7 @@ function use(input, argument) {
|
|
|
946
1120
|
let current;
|
|
947
1121
|
const onUpdate = (next, initial) => {
|
|
948
1122
|
if (mode === true && !initial)
|
|
949
|
-
throw Oops$
|
|
1123
|
+
throw Oops$1.IsReadOnly(subject, key);
|
|
950
1124
|
if (next) {
|
|
951
1125
|
current = next instanceof Model
|
|
952
1126
|
? next : bootstrap(next);
|
|
@@ -954,7 +1128,7 @@ function use(input, argument) {
|
|
|
954
1128
|
manage(current);
|
|
955
1129
|
}
|
|
956
1130
|
else if (mode === undefined)
|
|
957
|
-
throw Oops$
|
|
1131
|
+
throw Oops$1.UndefinedNotAllowed(key);
|
|
958
1132
|
else
|
|
959
1133
|
current = undefined;
|
|
960
1134
|
if (typeof argument == "function")
|
|
@@ -966,11 +1140,11 @@ function use(input, argument) {
|
|
|
966
1140
|
input instanceof Model ? input :
|
|
967
1141
|
typeof input === "function" ? input() :
|
|
968
1142
|
typeof input === "object" ? bootstrap(input) :
|
|
969
|
-
Oops$
|
|
1143
|
+
Oops$1.BadArgument(typeof input).throw();
|
|
970
1144
|
if (current)
|
|
971
1145
|
mode = onUpdate(current, true) || mode;
|
|
972
1146
|
else if (mode == true)
|
|
973
|
-
throw Oops$
|
|
1147
|
+
throw Oops$1.MustBeDefined(subject, key);
|
|
974
1148
|
}
|
|
975
1149
|
else
|
|
976
1150
|
mode = false;
|
|
@@ -985,40 +1159,14 @@ function parent(Expects, required) {
|
|
|
985
1159
|
const value = Parent.get(this.subject);
|
|
986
1160
|
if (!value) {
|
|
987
1161
|
if (required)
|
|
988
|
-
throw Oops$
|
|
1162
|
+
throw Oops$1.ParentRequired(expected, child);
|
|
989
1163
|
}
|
|
990
1164
|
else if (!(value instanceof Expects))
|
|
991
|
-
throw Oops$
|
|
1165
|
+
throw Oops$1.UnexpectedParent(expected, child, value);
|
|
992
1166
|
return { value };
|
|
993
1167
|
});
|
|
994
1168
|
}
|
|
995
1169
|
|
|
996
|
-
const Oops$2 = issues({
|
|
997
|
-
DuplicateAction: (key) => `Invoked action ${key} but one is already active.`,
|
|
998
|
-
BadComputedSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
999
|
-
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`
|
|
1000
|
-
});
|
|
1001
|
-
function createRef(key, cb) {
|
|
1002
|
-
const refObjectFunction = this.setter(key, cb && createValueEffect(cb));
|
|
1003
|
-
defineProperty(refObjectFunction, "current", {
|
|
1004
|
-
set: refObjectFunction,
|
|
1005
|
-
get: () => this.state[key]
|
|
1006
|
-
});
|
|
1007
|
-
return refObjectFunction;
|
|
1008
|
-
}
|
|
1009
|
-
function ref(arg) {
|
|
1010
|
-
return apply(function ref(key) {
|
|
1011
|
-
let value = {};
|
|
1012
|
-
if (typeof arg == "object") {
|
|
1013
|
-
const source = manage(arg);
|
|
1014
|
-
for (const key in source.state)
|
|
1015
|
-
defineLazy(value, key, createRef.bind(source, key));
|
|
1016
|
-
}
|
|
1017
|
-
else
|
|
1018
|
-
value = createRef.call(this, key, arg);
|
|
1019
|
-
return { value };
|
|
1020
|
-
});
|
|
1021
|
-
}
|
|
1022
1170
|
function on(initial, cb) {
|
|
1023
1171
|
return apply(function on(key) {
|
|
1024
1172
|
this.manage(key, initial, cb && createValueEffect(cb));
|
|
@@ -1042,132 +1190,6 @@ function lazy(value) {
|
|
|
1042
1190
|
get: () => source[key]
|
|
1043
1191
|
});
|
|
1044
1192
|
});
|
|
1045
|
-
}
|
|
1046
|
-
function act(task) {
|
|
1047
|
-
return apply(function act(key) {
|
|
1048
|
-
let pending = false;
|
|
1049
|
-
const invoke = (...args) => {
|
|
1050
|
-
if (pending)
|
|
1051
|
-
return Promise.reject(Oops$2.DuplicateAction(key));
|
|
1052
|
-
pending = true;
|
|
1053
|
-
this.update(key);
|
|
1054
|
-
return new Promise(res => {
|
|
1055
|
-
res(task.apply(this.subject, args));
|
|
1056
|
-
}).finally(() => {
|
|
1057
|
-
pending = false;
|
|
1058
|
-
this.update(key);
|
|
1059
|
-
});
|
|
1060
|
-
};
|
|
1061
|
-
setAlias(invoke, `run ${key}`);
|
|
1062
|
-
defineProperty(invoke, "active", {
|
|
1063
|
-
get: () => pending
|
|
1064
|
-
});
|
|
1065
|
-
return {
|
|
1066
|
-
value: invoke,
|
|
1067
|
-
writable: false
|
|
1068
|
-
};
|
|
1069
|
-
});
|
|
1070
|
-
}
|
|
1071
|
-
function from(source, setter, getter) {
|
|
1072
|
-
return apply(function from(key) {
|
|
1073
|
-
const { subject } = this;
|
|
1074
|
-
let getSource;
|
|
1075
|
-
// Easy mistake, using a peer, will always be unresolved.
|
|
1076
|
-
if (typeof source == "symbol")
|
|
1077
|
-
throw Oops$2.PeerNotAllowed(subject, key);
|
|
1078
|
-
// replace source controller in-case different
|
|
1079
|
-
if (typeof source == "object")
|
|
1080
|
-
getSource = () => manage(source);
|
|
1081
|
-
// specifically an arrow function (getter factory)
|
|
1082
|
-
else if (!source.prototype) {
|
|
1083
|
-
setter = source.call(subject, key);
|
|
1084
|
-
getSource = () => this;
|
|
1085
|
-
}
|
|
1086
|
-
// is a peer Model (constructor)
|
|
1087
|
-
else if (Model.isTypeof(source))
|
|
1088
|
-
getSource = pendingAccess(subject, source, key, true);
|
|
1089
|
-
// Regular function is to ambiguous so not allowed.
|
|
1090
|
-
else
|
|
1091
|
-
throw Oops$2.BadComputedSource(subject, key, source);
|
|
1092
|
-
prepare(this, key, getSource, setter, getter);
|
|
1093
|
-
});
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
const Oops$1 = issues({
|
|
1097
|
-
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
1098
|
-
});
|
|
1099
|
-
function pending(source, compute) {
|
|
1100
|
-
return (source === undefined ?
|
|
1101
|
-
suspendForValue() :
|
|
1102
|
-
typeof source == "function" && !source.prototype ?
|
|
1103
|
-
suspendForAsync(source) :
|
|
1104
|
-
suspendForComputed(source, compute));
|
|
1105
|
-
}
|
|
1106
|
-
/**
|
|
1107
|
-
* Get value, suspend instead if undefined.
|
|
1108
|
-
*
|
|
1109
|
-
* Throws suspense promise also interpretable as an error.
|
|
1110
|
-
* React could handle it but other contexts probably not.
|
|
1111
|
-
*/
|
|
1112
|
-
function pendingValue(via, key) {
|
|
1113
|
-
const value = via.state[key];
|
|
1114
|
-
if (value !== undefined)
|
|
1115
|
-
return value;
|
|
1116
|
-
const error = Oops$1.ValueNotReady(via.subject, key);
|
|
1117
|
-
const promise = new Promise(resolve => {
|
|
1118
|
-
const release = via.addListener({
|
|
1119
|
-
[key](value) {
|
|
1120
|
-
if (value !== undefined) {
|
|
1121
|
-
release();
|
|
1122
|
-
resolve();
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
});
|
|
1126
|
-
});
|
|
1127
|
-
throw Object.assign(promise, {
|
|
1128
|
-
toString: () => String(error),
|
|
1129
|
-
message: error.message,
|
|
1130
|
-
stack: error.stack
|
|
1131
|
-
});
|
|
1132
|
-
}
|
|
1133
|
-
function suspendForComputed(source, compute) {
|
|
1134
|
-
function getter(_value, key) {
|
|
1135
|
-
return pendingValue(manage(this), key);
|
|
1136
|
-
}
|
|
1137
|
-
return from(source, compute, getter);
|
|
1138
|
-
}
|
|
1139
|
-
function suspendForValue() {
|
|
1140
|
-
return apply(function pending(key) {
|
|
1141
|
-
this.state[key] = undefined;
|
|
1142
|
-
return {
|
|
1143
|
-
set: this.setter(key),
|
|
1144
|
-
get: () => pendingValue(this, key)
|
|
1145
|
-
};
|
|
1146
|
-
});
|
|
1147
|
-
}
|
|
1148
|
-
function suspendForAsync(source) {
|
|
1149
|
-
return apply(function suspense(key) {
|
|
1150
|
-
const subject = this.subject;
|
|
1151
|
-
let waiting = true;
|
|
1152
|
-
let value;
|
|
1153
|
-
let error;
|
|
1154
|
-
return () => {
|
|
1155
|
-
if (error)
|
|
1156
|
-
throw error;
|
|
1157
|
-
if (!waiting)
|
|
1158
|
-
return value;
|
|
1159
|
-
const issue = Oops$1.ValueNotReady(subject, key);
|
|
1160
|
-
let suspend = source
|
|
1161
|
-
.call(subject, key)
|
|
1162
|
-
.catch(err => error = err)
|
|
1163
|
-
.then(out => value = out)
|
|
1164
|
-
.finally(() => waiting = false);
|
|
1165
|
-
throw Object.assign(suspend, {
|
|
1166
|
-
message: issue.message,
|
|
1167
|
-
stack: issue.stack
|
|
1168
|
-
});
|
|
1169
|
-
};
|
|
1170
|
-
});
|
|
1171
1193
|
}
|
|
1172
1194
|
|
|
1173
1195
|
const Oops = issues({
|