@expressive/mvc 0.17.1 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +128 -209
- package/lib/index.esm.js +308 -652
- package/lib/index.js +313 -661
- package/package.json +2 -14
- package/README.md +0 -1666
package/lib/index.js
CHANGED
|
@@ -2,11 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
|
-
|
|
9
|
-
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
5
|
+
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
10
6
|
|
|
11
7
|
class Issue extends Error {
|
|
12
8
|
constructor() {
|
|
@@ -25,31 +21,17 @@ function issues(register) {
|
|
|
25
21
|
return Library;
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
29
|
-
const UID_CACHE = new WeakMap();
|
|
30
|
-
function assignWeak(into, from) {
|
|
31
|
-
for (const K in from)
|
|
32
|
-
if (K in into)
|
|
33
|
-
into[K] = from[K];
|
|
34
|
-
}
|
|
35
|
-
function uid(object) {
|
|
36
|
-
let uid = UID_CACHE.get(object);
|
|
37
|
-
if (!uid)
|
|
38
|
-
UID_CACHE.set(object, uid = Math.random());
|
|
39
|
-
return uid;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
24
|
const REGISTER$1 = new WeakMap();
|
|
43
25
|
class Subscriber {
|
|
44
|
-
constructor(parent, onUpdate
|
|
45
|
-
this.parent = parent;
|
|
26
|
+
constructor(parent, onUpdate) {
|
|
46
27
|
this.onUpdate = onUpdate;
|
|
47
|
-
this.strict = strict;
|
|
48
28
|
this.active = false;
|
|
49
29
|
this.dependant = new Set();
|
|
50
30
|
this.watch = new Map();
|
|
51
|
-
|
|
31
|
+
if (!(parent instanceof Control))
|
|
32
|
+
parent = Control.for(parent);
|
|
52
33
|
const reset = () => this.latest = undefined;
|
|
34
|
+
const proxy = create(parent.subject);
|
|
53
35
|
REGISTER$1.set(proxy, this);
|
|
54
36
|
defineProperty(this, "proxy", {
|
|
55
37
|
configurable: true,
|
|
@@ -58,6 +40,7 @@ class Subscriber {
|
|
|
58
40
|
return proxy;
|
|
59
41
|
}
|
|
60
42
|
});
|
|
43
|
+
this.parent = parent;
|
|
61
44
|
this.clear = parent.addListener(key => {
|
|
62
45
|
if (this.active)
|
|
63
46
|
this.notify(key);
|
|
@@ -66,15 +49,11 @@ class Subscriber {
|
|
|
66
49
|
get using() {
|
|
67
50
|
return Array.from(this.watch.keys());
|
|
68
51
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
for (const key of keys)
|
|
75
|
-
if (key in values)
|
|
76
|
-
subject[key] = values[key];
|
|
77
|
-
waiting.add(() => this.active = true);
|
|
52
|
+
get(key, using) {
|
|
53
|
+
this.follow(key);
|
|
54
|
+
return using
|
|
55
|
+
? using(this)
|
|
56
|
+
: this.parent.state.get(key);
|
|
78
57
|
}
|
|
79
58
|
follow(key, value) {
|
|
80
59
|
if (value !== undefined)
|
|
@@ -110,11 +89,11 @@ function subscriber(from) {
|
|
|
110
89
|
return REGISTER$1.get(from);
|
|
111
90
|
}
|
|
112
91
|
|
|
113
|
-
const Oops$
|
|
92
|
+
const Oops$8 = issues({
|
|
114
93
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
115
94
|
});
|
|
116
95
|
function suspend(source, key) {
|
|
117
|
-
const error = Oops$
|
|
96
|
+
const error = Oops$8.NotReady(source.subject, key);
|
|
118
97
|
const promise = new Promise(resolve => {
|
|
119
98
|
const release = source.addListener(forKey => {
|
|
120
99
|
if (forKey == key)
|
|
@@ -154,87 +133,7 @@ function mayRetry(fn) {
|
|
|
154
133
|
return compute();
|
|
155
134
|
}
|
|
156
135
|
|
|
157
|
-
const
|
|
158
|
-
const Oops$b = issues({
|
|
159
|
-
BadAssignment: (parent, expected, got) => `Property ${parent} expected Model of type ${expected} but got ${got}.`,
|
|
160
|
-
Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
|
|
161
|
-
Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
162
|
-
});
|
|
163
|
-
function getParentForGetInstruction(type, relativeTo, required) {
|
|
164
|
-
const item = getParent(type, relativeTo);
|
|
165
|
-
return (_refresh) => {
|
|
166
|
-
if (item)
|
|
167
|
-
return item;
|
|
168
|
-
if (required)
|
|
169
|
-
throw Oops$b.Required(type.name, relativeTo);
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
function getParent(type, from) {
|
|
173
|
-
const value = Parent.get(from);
|
|
174
|
-
if (value && !(value instanceof type))
|
|
175
|
-
throw Oops$b.Unexpected(type.name, from, value);
|
|
176
|
-
return value;
|
|
177
|
-
}
|
|
178
|
-
function getRecursive(key, from) {
|
|
179
|
-
const context = new WeakMap();
|
|
180
|
-
const { state } = from;
|
|
181
|
-
return (local) => {
|
|
182
|
-
if (!state.has(key))
|
|
183
|
-
throw suspend(from, key);
|
|
184
|
-
if (!local)
|
|
185
|
-
return state.get(key);
|
|
186
|
-
if (!context.has(local)) {
|
|
187
|
-
let reset;
|
|
188
|
-
const init = () => {
|
|
189
|
-
if (reset)
|
|
190
|
-
reset();
|
|
191
|
-
const value = state.get(key);
|
|
192
|
-
if (value && controller(value)) {
|
|
193
|
-
const child = new Subscriber(control(value), local.onUpdate);
|
|
194
|
-
if (local.active)
|
|
195
|
-
child.commit();
|
|
196
|
-
local.dependant.add(child);
|
|
197
|
-
context.set(local, child.proxy);
|
|
198
|
-
reset = () => {
|
|
199
|
-
child.release();
|
|
200
|
-
local.dependant.delete(child);
|
|
201
|
-
context.set(local, undefined);
|
|
202
|
-
reset = undefined;
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
local.follow(key, init);
|
|
207
|
-
init();
|
|
208
|
-
}
|
|
209
|
-
return context.get(local);
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
function setRecursive(controller, key, initial) {
|
|
213
|
-
const { state, subject } = controller;
|
|
214
|
-
const Type = initial.constructor;
|
|
215
|
-
let get;
|
|
216
|
-
const onUpdate = (next) => {
|
|
217
|
-
state.set(key, next);
|
|
218
|
-
if (!(next instanceof Type))
|
|
219
|
-
throw Oops$b.BadAssignment(`${subject}.${key}`, Type.name, String(next));
|
|
220
|
-
get = getRecursive(key, controller);
|
|
221
|
-
Parent.set(next, subject);
|
|
222
|
-
control(next);
|
|
223
|
-
return true;
|
|
224
|
-
};
|
|
225
|
-
onUpdate(initial);
|
|
226
|
-
defineProperty(subject, key, {
|
|
227
|
-
set: controller.ref(key, onUpdate),
|
|
228
|
-
get() {
|
|
229
|
-
const local = subscriber(this);
|
|
230
|
-
if (local)
|
|
231
|
-
local.follow(key);
|
|
232
|
-
return get(local);
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const Oops$a = issues({
|
|
136
|
+
const Oops$7 = issues({
|
|
238
137
|
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
239
138
|
});
|
|
240
139
|
function createEffect(model, callback, keys) {
|
|
@@ -248,7 +147,7 @@ function createEffect(model, callback, keys) {
|
|
|
248
147
|
if (unSet instanceof Promise)
|
|
249
148
|
unSet = undefined;
|
|
250
149
|
if (unSet && typeof unSet !== "function")
|
|
251
|
-
throw Oops$
|
|
150
|
+
throw Oops$7.BadCallback();
|
|
252
151
|
}
|
|
253
152
|
function invoke() {
|
|
254
153
|
if (busy)
|
|
@@ -292,11 +191,11 @@ function createValueEffect(callback) {
|
|
|
292
191
|
if (typeof out == "function")
|
|
293
192
|
unSet = out;
|
|
294
193
|
else
|
|
295
|
-
throw Oops$
|
|
194
|
+
throw Oops$7.BadCallback();
|
|
296
195
|
};
|
|
297
196
|
}
|
|
298
197
|
|
|
299
|
-
const Oops$
|
|
198
|
+
const Oops$6 = issues({
|
|
300
199
|
Timeout: (keys, timeout) => `No update seen for [${keys}] within ${timeout}.`,
|
|
301
200
|
KeysExpected: (key) => `Key "${key}" was expected in current update.`,
|
|
302
201
|
StrictUpdate: () => `Expected update but none in progress.`,
|
|
@@ -332,13 +231,13 @@ function awaitUpdate(source, arg1, arg2) {
|
|
|
332
231
|
const timeout = (message) => {
|
|
333
232
|
const k = keys ? keys.join(", ") : "any";
|
|
334
233
|
removeListener();
|
|
335
|
-
reject(Oops$
|
|
234
|
+
reject(Oops$6.Timeout(k, message));
|
|
336
235
|
};
|
|
337
236
|
const removeListener = control(source, controller => {
|
|
338
237
|
const pending = controller.frame;
|
|
339
238
|
if (keys === null) {
|
|
340
239
|
if (pending.size)
|
|
341
|
-
reject(Oops$
|
|
240
|
+
reject(Oops$6.StrictNoUpdate());
|
|
342
241
|
else
|
|
343
242
|
resolve(null);
|
|
344
243
|
return;
|
|
@@ -346,7 +245,7 @@ function awaitUpdate(source, arg1, arg2) {
|
|
|
346
245
|
if (keys) {
|
|
347
246
|
if (keys.length) {
|
|
348
247
|
if (arg2 === 0 && single && !pending.has(keys[0])) {
|
|
349
|
-
reject(Oops$
|
|
248
|
+
reject(Oops$6.KeysExpected(keys[0]));
|
|
350
249
|
return;
|
|
351
250
|
}
|
|
352
251
|
else
|
|
@@ -358,7 +257,7 @@ function awaitUpdate(source, arg1, arg2) {
|
|
|
358
257
|
}
|
|
359
258
|
}
|
|
360
259
|
else if (!pending.size && arg1 === true || arg2 === 0) {
|
|
361
|
-
reject(Oops$
|
|
260
|
+
reject(Oops$6.StrictUpdate());
|
|
362
261
|
return;
|
|
363
262
|
}
|
|
364
263
|
else
|
|
@@ -381,8 +280,9 @@ function awaitUpdate(source, arg1, arg2) {
|
|
|
381
280
|
});
|
|
382
281
|
}
|
|
383
282
|
|
|
384
|
-
const Oops$
|
|
385
|
-
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining
|
|
283
|
+
const Oops$5 = issues({
|
|
284
|
+
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`,
|
|
285
|
+
NoAdapter: (method) => `Can't call Model.${method} without an adapter.`
|
|
386
286
|
});
|
|
387
287
|
class Model {
|
|
388
288
|
constructor() {
|
|
@@ -399,14 +299,14 @@ class Model {
|
|
|
399
299
|
}
|
|
400
300
|
get(arg1, arg2) {
|
|
401
301
|
const { state } = control(this);
|
|
402
|
-
const extract =
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
302
|
+
const extract = () => {
|
|
303
|
+
if (typeof arg1 == "string")
|
|
304
|
+
return state.get(arg1);
|
|
305
|
+
const output = {};
|
|
306
|
+
for (const key of arg1 || state.keys())
|
|
307
|
+
output[key] = state.get(key);
|
|
308
|
+
return output;
|
|
309
|
+
};
|
|
410
310
|
if (!arg1 || arg2 === undefined)
|
|
411
311
|
return extract();
|
|
412
312
|
if (typeof arg2 == "function")
|
|
@@ -439,15 +339,13 @@ class Model {
|
|
|
439
339
|
return {
|
|
440
340
|
then: (callback) => {
|
|
441
341
|
if (!callback)
|
|
442
|
-
throw Oops$
|
|
342
|
+
throw Oops$5.NoChaining();
|
|
443
343
|
controller.waiting.add(callback);
|
|
444
344
|
}
|
|
445
345
|
};
|
|
446
346
|
}
|
|
447
|
-
/**
|
|
448
|
-
|
|
449
|
-
*/
|
|
450
|
-
end() {
|
|
347
|
+
/** Mark this instance for garbage collection. */
|
|
348
|
+
gc() {
|
|
451
349
|
control(this).clear();
|
|
452
350
|
}
|
|
453
351
|
/**
|
|
@@ -462,6 +360,18 @@ class Model {
|
|
|
462
360
|
control(instance);
|
|
463
361
|
return instance;
|
|
464
362
|
}
|
|
363
|
+
static use() {
|
|
364
|
+
throw Oops$5.NoAdapter("use");
|
|
365
|
+
}
|
|
366
|
+
static get() {
|
|
367
|
+
throw Oops$5.NoAdapter("get");
|
|
368
|
+
}
|
|
369
|
+
static tap() {
|
|
370
|
+
throw Oops$5.NoAdapter("tap");
|
|
371
|
+
}
|
|
372
|
+
static meta() {
|
|
373
|
+
throw Oops$5.NoAdapter("meta");
|
|
374
|
+
}
|
|
465
375
|
/**
|
|
466
376
|
* Static equivalent of `x instanceof this`.
|
|
467
377
|
*
|
|
@@ -476,114 +386,172 @@ defineProperty(Model.prototype, "toString", {
|
|
|
476
386
|
value() {
|
|
477
387
|
return this.constructor.name;
|
|
478
388
|
}
|
|
479
|
-
});
|
|
480
|
-
const FindInstruction = new WeakMap([
|
|
481
|
-
[Model, getParentForGetInstruction]
|
|
482
|
-
]);
|
|
389
|
+
});
|
|
483
390
|
|
|
484
|
-
|
|
391
|
+
/**
|
|
392
|
+
* Run instruction as controller sets itself up.
|
|
393
|
+
* This will specialize the behavior of a given property.
|
|
394
|
+
*/
|
|
395
|
+
function add(instruction, label) {
|
|
396
|
+
const name = label || instruction.name || "pending";
|
|
397
|
+
const placeholder = Symbol(`${name} instruction`);
|
|
398
|
+
PENDING.set(placeholder, (control, key) => {
|
|
399
|
+
let output = instruction.call(control, key, control);
|
|
400
|
+
if (!output)
|
|
401
|
+
return undefined;
|
|
402
|
+
if (typeof output == "function")
|
|
403
|
+
output = { get: output };
|
|
404
|
+
if ("value" in output)
|
|
405
|
+
control.state.set(key, output.value);
|
|
406
|
+
let { enumerable, get, set } = output;
|
|
407
|
+
defineProperty(control.subject, key, {
|
|
408
|
+
enumerable,
|
|
409
|
+
set: (set === false
|
|
410
|
+
? undefined
|
|
411
|
+
: control.ref(key, set)),
|
|
412
|
+
get() {
|
|
413
|
+
const local = subscriber(this);
|
|
414
|
+
return (local ? local.get(key, get) :
|
|
415
|
+
get ? get(local) :
|
|
416
|
+
control.state.get(key));
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
return placeholder;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const Oops$4 = issues({
|
|
485
424
|
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or get) as computed source for ${model}.${property}. This is not allowed.`,
|
|
486
|
-
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}]
|
|
425
|
+
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
426
|
+
Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
|
|
487
427
|
});
|
|
488
428
|
function get(arg0, arg1) {
|
|
429
|
+
const fetch = this || getParentForGetInstruction;
|
|
489
430
|
return add(function get(key) {
|
|
490
|
-
|
|
491
|
-
// Easy mistake, using a peer, will always be unresolved.
|
|
431
|
+
let { subject } = this;
|
|
492
432
|
if (typeof arg0 == "symbol")
|
|
493
|
-
throw Oops$
|
|
494
|
-
let source;
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
}
|
|
501
|
-
else if (Model.isTypeof(arg0)) {
|
|
502
|
-
source = find(arg0, subject, sourceRequired);
|
|
503
|
-
}
|
|
504
|
-
else if (typeof arg0 == "function") {
|
|
433
|
+
throw Oops$4.PeerNotAllowed(subject, key);
|
|
434
|
+
let source = cb => cb(subject);
|
|
435
|
+
if (arg0 instanceof Model)
|
|
436
|
+
subject = arg0;
|
|
437
|
+
else if (Model.isTypeof(arg0))
|
|
438
|
+
source = fetch(arg0, subject, arg1 !== false);
|
|
439
|
+
else if (typeof arg0 == "function")
|
|
505
440
|
arg1 = arg0.call(subject, key, subject);
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
441
|
+
return typeof arg1 == "function"
|
|
442
|
+
? getComputed(key, this, source, arg1)
|
|
443
|
+
: getRecursive$1(key, this, source, arg1);
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
function getParentForGetInstruction(type, relativeTo, required) {
|
|
447
|
+
const item = getParent(relativeTo, type);
|
|
448
|
+
return callback => {
|
|
449
|
+
if (item)
|
|
450
|
+
callback(item);
|
|
451
|
+
else if (required)
|
|
452
|
+
throw Oops$4.Required(type.name, relativeTo);
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
function getRecursive$1(key, parent, source, required) {
|
|
456
|
+
const context = new WeakMap();
|
|
457
|
+
const { state } = parent;
|
|
458
|
+
let waiting;
|
|
459
|
+
source((got) => {
|
|
460
|
+
state.set(key, got);
|
|
461
|
+
if (waiting)
|
|
462
|
+
parent.update(key);
|
|
520
463
|
});
|
|
464
|
+
waiting = true;
|
|
465
|
+
function create(local) {
|
|
466
|
+
let reset;
|
|
467
|
+
local.follow(key, init);
|
|
468
|
+
init();
|
|
469
|
+
function init() {
|
|
470
|
+
if (reset)
|
|
471
|
+
reset();
|
|
472
|
+
const value = state.get(key);
|
|
473
|
+
if (value && controller(value)) {
|
|
474
|
+
const child = new Subscriber(value, local.onUpdate);
|
|
475
|
+
if (local.active)
|
|
476
|
+
child.commit();
|
|
477
|
+
local.dependant.add(child);
|
|
478
|
+
context.set(local, child.proxy);
|
|
479
|
+
reset = () => {
|
|
480
|
+
child.release();
|
|
481
|
+
local.dependant.delete(child);
|
|
482
|
+
context.set(local, undefined);
|
|
483
|
+
reset = undefined;
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return (local) => {
|
|
489
|
+
const value = state.get(key);
|
|
490
|
+
if (!value && required !== false)
|
|
491
|
+
parent.waitFor(key);
|
|
492
|
+
if (!local)
|
|
493
|
+
return value;
|
|
494
|
+
if (!context.has(local))
|
|
495
|
+
create(local);
|
|
496
|
+
return context.get(local);
|
|
497
|
+
};
|
|
521
498
|
}
|
|
522
499
|
function getComputed(key, parent, source, setter) {
|
|
523
500
|
const { state } = parent;
|
|
524
|
-
let
|
|
501
|
+
let local;
|
|
502
|
+
let active;
|
|
503
|
+
let isAsync;
|
|
525
504
|
let order = ORDER.get(parent);
|
|
526
505
|
let pending = KEYS.get(parent);
|
|
527
|
-
let instance;
|
|
528
506
|
if (!order)
|
|
529
507
|
ORDER.set(parent, order = new Map());
|
|
530
508
|
if (!pending)
|
|
531
509
|
KEYS.set(parent, pending = new Set());
|
|
532
|
-
|
|
510
|
+
INFO.set(compute, key);
|
|
511
|
+
function compute(initial) {
|
|
512
|
+
let next;
|
|
533
513
|
try {
|
|
534
|
-
|
|
514
|
+
next = setter.call(local.proxy, local.proxy);
|
|
535
515
|
}
|
|
536
516
|
catch (err) {
|
|
537
|
-
Oops$
|
|
538
|
-
|
|
517
|
+
Oops$4.Failed(parent.subject, key, initial).warn();
|
|
518
|
+
if (initial)
|
|
519
|
+
throw err;
|
|
520
|
+
console.error(err);
|
|
539
521
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
522
|
+
if (next !== state.get(key)) {
|
|
523
|
+
state.set(key, next);
|
|
524
|
+
if (!initial || isAsync)
|
|
525
|
+
parent.update(key);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function connect(model) {
|
|
529
|
+
local = new Subscriber(model, (_, control) => {
|
|
548
530
|
if (control !== parent)
|
|
549
|
-
|
|
531
|
+
compute();
|
|
550
532
|
else
|
|
551
|
-
pending.add(
|
|
533
|
+
pending.add(compute);
|
|
552
534
|
});
|
|
553
|
-
|
|
535
|
+
local.watch.set(key, false);
|
|
554
536
|
try {
|
|
555
|
-
|
|
556
|
-
state.set(key, value);
|
|
557
|
-
return value;
|
|
537
|
+
compute(true);
|
|
558
538
|
}
|
|
559
539
|
finally {
|
|
560
|
-
|
|
561
|
-
order.set(
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
|
-
const refresh = () => {
|
|
565
|
-
let value;
|
|
566
|
-
try {
|
|
567
|
-
value = compute(false);
|
|
568
|
-
}
|
|
569
|
-
catch (e) {
|
|
570
|
-
console.error(e);
|
|
540
|
+
local.commit();
|
|
541
|
+
order.set(compute, order.size);
|
|
571
542
|
}
|
|
572
|
-
|
|
573
|
-
if (state.get(key) !== value) {
|
|
574
|
-
state.set(key, value);
|
|
575
|
-
parent.update(key);
|
|
576
|
-
return value;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
};
|
|
580
|
-
INFO.set(refresh, key);
|
|
543
|
+
}
|
|
581
544
|
return () => {
|
|
582
|
-
if (
|
|
583
|
-
|
|
584
|
-
|
|
545
|
+
if (!active) {
|
|
546
|
+
active = true;
|
|
547
|
+
source(connect);
|
|
548
|
+
isAsync = true;
|
|
585
549
|
}
|
|
586
|
-
|
|
550
|
+
if (!local)
|
|
551
|
+
parent.waitFor(key);
|
|
552
|
+
if (pending.delete(compute))
|
|
553
|
+
compute();
|
|
554
|
+
return state.get(key);
|
|
587
555
|
};
|
|
588
556
|
}
|
|
589
557
|
const INFO = new WeakMap();
|
|
@@ -606,16 +574,10 @@ function flush(control) {
|
|
|
606
574
|
}
|
|
607
575
|
pending.clear();
|
|
608
576
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
T = getPrototypeOf(T);
|
|
614
|
-
const getter = FindInstruction.get(T);
|
|
615
|
-
if (getter)
|
|
616
|
-
return getter(type, relativeTo, required);
|
|
617
|
-
} while (T.prototype instanceof Model);
|
|
618
|
-
}
|
|
577
|
+
function using(fn) {
|
|
578
|
+
return Object.assign(get.bind(fn), { using });
|
|
579
|
+
}
|
|
580
|
+
get.using = using;
|
|
619
581
|
|
|
620
582
|
const REGISTER = new WeakMap();
|
|
621
583
|
const PENDING = new Map();
|
|
@@ -650,17 +612,17 @@ class Control {
|
|
|
650
612
|
enumerable: false,
|
|
651
613
|
set: this.ref(key),
|
|
652
614
|
get() {
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
if (value === undefined && sub.strict)
|
|
658
|
-
throw suspend(this, key);
|
|
659
|
-
}
|
|
660
|
-
return value;
|
|
615
|
+
const local = subscriber(this);
|
|
616
|
+
return local
|
|
617
|
+
? local.get(key)
|
|
618
|
+
: state.get(key);
|
|
661
619
|
}
|
|
662
620
|
});
|
|
663
621
|
}
|
|
622
|
+
/** Throw suspense which resolves when key is set. */
|
|
623
|
+
waitFor(key) {
|
|
624
|
+
throw suspend(this, key);
|
|
625
|
+
}
|
|
664
626
|
addListener(listener) {
|
|
665
627
|
this.followers.add(listener);
|
|
666
628
|
return () => {
|
|
@@ -746,46 +708,72 @@ function control(subject, cb) {
|
|
|
746
708
|
return cb ? cb(control) : control;
|
|
747
709
|
}
|
|
748
710
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
const
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
const
|
|
772
|
-
if (
|
|
773
|
-
local.
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
711
|
+
const Parent = new WeakMap();
|
|
712
|
+
const Oops$3 = issues({
|
|
713
|
+
BadAssignment: (parent, expected, got) => `Property ${parent} expected Model of type ${expected} but got ${got}.`,
|
|
714
|
+
Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
715
|
+
});
|
|
716
|
+
function getParent(from, type) {
|
|
717
|
+
const value = Parent.get(from);
|
|
718
|
+
if (value && type && !(value instanceof type))
|
|
719
|
+
throw Oops$3.Unexpected(type.name, from, value);
|
|
720
|
+
return value;
|
|
721
|
+
}
|
|
722
|
+
function getRecursive(key, from) {
|
|
723
|
+
const context = new WeakMap();
|
|
724
|
+
const { state } = from;
|
|
725
|
+
return (local) => {
|
|
726
|
+
if (!local)
|
|
727
|
+
return state.get(key);
|
|
728
|
+
if (!context.has(local)) {
|
|
729
|
+
let reset;
|
|
730
|
+
const init = () => {
|
|
731
|
+
if (reset)
|
|
732
|
+
reset();
|
|
733
|
+
const value = state.get(key);
|
|
734
|
+
if (value && controller(value)) {
|
|
735
|
+
const child = new Subscriber(value, local.onUpdate);
|
|
736
|
+
if (local.active)
|
|
737
|
+
child.commit();
|
|
738
|
+
local.dependant.add(child);
|
|
739
|
+
context.set(local, child.proxy);
|
|
740
|
+
reset = () => {
|
|
741
|
+
child.release();
|
|
742
|
+
local.dependant.delete(child);
|
|
743
|
+
context.set(local, undefined);
|
|
744
|
+
reset = undefined;
|
|
745
|
+
};
|
|
784
746
|
}
|
|
785
|
-
}
|
|
786
|
-
|
|
747
|
+
};
|
|
748
|
+
local.follow(key, init);
|
|
749
|
+
init();
|
|
750
|
+
}
|
|
751
|
+
return context.get(local);
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
function setRecursive(controller, key, initial) {
|
|
755
|
+
const { state, subject } = controller;
|
|
756
|
+
const Type = initial.constructor;
|
|
757
|
+
let get;
|
|
758
|
+
const onUpdate = (next) => {
|
|
759
|
+
state.set(key, next);
|
|
760
|
+
if (!(next instanceof Type))
|
|
761
|
+
throw Oops$3.BadAssignment(`${subject}.${key}`, Type.name, String(next));
|
|
762
|
+
get = getRecursive(key, controller);
|
|
763
|
+
Parent.set(next, subject);
|
|
764
|
+
control(next);
|
|
765
|
+
return true;
|
|
766
|
+
};
|
|
767
|
+
onUpdate(initial);
|
|
768
|
+
defineProperty(subject, key, {
|
|
769
|
+
set: controller.ref(key, onUpdate),
|
|
770
|
+
get() {
|
|
771
|
+
const local = subscriber(this);
|
|
772
|
+
if (local)
|
|
773
|
+
local.follow(key);
|
|
774
|
+
return get(local);
|
|
775
|
+
}
|
|
787
776
|
});
|
|
788
|
-
return placeholder;
|
|
789
777
|
}
|
|
790
778
|
|
|
791
779
|
/******************************************************************************
|
|
@@ -813,7 +801,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
813
801
|
});
|
|
814
802
|
}
|
|
815
803
|
|
|
816
|
-
const Oops$
|
|
804
|
+
const Oops$2 = issues({
|
|
817
805
|
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
818
806
|
});
|
|
819
807
|
function run(task) {
|
|
@@ -821,7 +809,7 @@ function run(task) {
|
|
|
821
809
|
let pending = false;
|
|
822
810
|
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
823
811
|
if (pending)
|
|
824
|
-
return Promise.reject(Oops$
|
|
812
|
+
return Promise.reject(Oops$2.DuplicatePending(key));
|
|
825
813
|
pending = true;
|
|
826
814
|
this.update(key);
|
|
827
815
|
try {
|
|
@@ -874,7 +862,7 @@ function createRef(src, key, cb) {
|
|
|
874
862
|
return refObjectFunction;
|
|
875
863
|
}
|
|
876
864
|
|
|
877
|
-
const Oops$
|
|
865
|
+
const Oops$1 = issues({
|
|
878
866
|
ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
|
|
879
867
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
880
868
|
});
|
|
@@ -908,7 +896,7 @@ function set(value, argument) {
|
|
|
908
896
|
const suspend = () => {
|
|
909
897
|
if (required === false)
|
|
910
898
|
return undefined;
|
|
911
|
-
const issue = Oops$
|
|
899
|
+
const issue = Oops$1.NotReady(subject, key);
|
|
912
900
|
assign(pending, {
|
|
913
901
|
message: issue.message,
|
|
914
902
|
stack: issue.stack
|
|
@@ -925,7 +913,7 @@ function set(value, argument) {
|
|
|
925
913
|
};
|
|
926
914
|
}
|
|
927
915
|
catch (err) {
|
|
928
|
-
Oops$
|
|
916
|
+
Oops$1.ComputeFailed(subject, key).warn();
|
|
929
917
|
throw err;
|
|
930
918
|
}
|
|
931
919
|
};
|
|
@@ -944,7 +932,7 @@ function set(value, argument) {
|
|
|
944
932
|
if (state.has(key))
|
|
945
933
|
return state.get(key);
|
|
946
934
|
else
|
|
947
|
-
|
|
935
|
+
this.waitFor(key);
|
|
948
936
|
},
|
|
949
937
|
set: typeof argument == "function"
|
|
950
938
|
? createValueEffect(argument)
|
|
@@ -1101,7 +1089,7 @@ function createProxy(emit, watch) {
|
|
|
1101
1089
|
};
|
|
1102
1090
|
}
|
|
1103
1091
|
|
|
1104
|
-
const Oops
|
|
1092
|
+
const Oops = issues({
|
|
1105
1093
|
BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
|
|
1106
1094
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
1107
1095
|
});
|
|
@@ -1117,7 +1105,7 @@ function use(input, argument) {
|
|
|
1117
1105
|
input = new input();
|
|
1118
1106
|
}
|
|
1119
1107
|
else if (input && typeof input !== "object")
|
|
1120
|
-
throw Oops
|
|
1108
|
+
throw Oops.BadArgument(typeof input);
|
|
1121
1109
|
if (input instanceof Map || input instanceof Set)
|
|
1122
1110
|
return keyed(this, key, input);
|
|
1123
1111
|
const onUpdate = (next) => {
|
|
@@ -1134,7 +1122,7 @@ function use(input, argument) {
|
|
|
1134
1122
|
const suspend = () => {
|
|
1135
1123
|
if (required === false)
|
|
1136
1124
|
return;
|
|
1137
|
-
const issue = Oops
|
|
1125
|
+
const issue = Oops.NotReady(subject, key);
|
|
1138
1126
|
assign(pending, {
|
|
1139
1127
|
message: issue.message,
|
|
1140
1128
|
stack: issue.stack
|
|
@@ -1179,6 +1167,42 @@ function use(input, argument) {
|
|
|
1179
1167
|
});
|
|
1180
1168
|
}
|
|
1181
1169
|
|
|
1170
|
+
const LOCAL = "$debug local";
|
|
1171
|
+
const STATE = "$debug state";
|
|
1172
|
+
const UPDATE = "$debug update";
|
|
1173
|
+
const CONTROL = "$debug controller";
|
|
1174
|
+
defineProperties(Model.prototype, {
|
|
1175
|
+
[CONTROL]: {
|
|
1176
|
+
get() {
|
|
1177
|
+
return controller(this);
|
|
1178
|
+
}
|
|
1179
|
+
},
|
|
1180
|
+
[LOCAL]: {
|
|
1181
|
+
get() {
|
|
1182
|
+
return subscriber(this);
|
|
1183
|
+
}
|
|
1184
|
+
},
|
|
1185
|
+
[STATE]: {
|
|
1186
|
+
get() {
|
|
1187
|
+
const { state } = controller(this);
|
|
1188
|
+
const output = {};
|
|
1189
|
+
state.forEach((value, key) => output[key] = value);
|
|
1190
|
+
return output;
|
|
1191
|
+
}
|
|
1192
|
+
},
|
|
1193
|
+
[UPDATE]: {
|
|
1194
|
+
get() {
|
|
1195
|
+
return (subscriber(this) || controller(this)).latest;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
const Debug = {
|
|
1200
|
+
CONTROL,
|
|
1201
|
+
LOCAL,
|
|
1202
|
+
STATE,
|
|
1203
|
+
UPDATE
|
|
1204
|
+
};
|
|
1205
|
+
|
|
1182
1206
|
class Register {
|
|
1183
1207
|
constructor() {
|
|
1184
1208
|
this.table = new Map();
|
|
@@ -1234,394 +1258,22 @@ class Register {
|
|
|
1234
1258
|
delete this[key];
|
|
1235
1259
|
}
|
|
1236
1260
|
for (const model of items)
|
|
1237
|
-
model.
|
|
1238
|
-
}
|
|
1239
|
-
delete(instance) {
|
|
1240
|
-
for (const key of getOwnPropertySymbols(this)) {
|
|
1241
|
-
const entry = getOwnPropertyDescriptor(this, key);
|
|
1242
|
-
if (entry.value === instance)
|
|
1243
|
-
delete this[key];
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
const Global$1 = new Register();
|
|
1248
|
-
|
|
1249
|
-
const Oops$3 = issues({
|
|
1250
|
-
AlreadyExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`,
|
|
1251
|
-
DoesNotExist: (name) => `Tried to access singleton ${name}, but none exist! Did you forget to initialize?\nCall ${name}.new() before attempting to access, or consider using ${name}.use() instead.`,
|
|
1252
|
-
NotFound: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`,
|
|
1253
|
-
MultipleExist: (name) => `Did find ${name} in context, but multiple were defined by same Provider.`
|
|
1254
|
-
});
|
|
1255
|
-
const LookupContext = React__default["default"].createContext(Global$1);
|
|
1256
|
-
function useLookup() {
|
|
1257
|
-
try {
|
|
1258
|
-
return React__default["default"].useContext(LookupContext);
|
|
1259
|
-
}
|
|
1260
|
-
catch (err) {
|
|
1261
|
-
return Global$1;
|
|
1261
|
+
model.gc();
|
|
1262
1262
|
}
|
|
1263
|
-
}
|
|
1264
|
-
function useContext(Type, required) {
|
|
1265
|
-
const instance = useLookup().get(Type);
|
|
1266
|
-
if (instance === null)
|
|
1267
|
-
throw Oops$3.MultipleExist(Type.name);
|
|
1268
|
-
if (!instance && required !== false)
|
|
1269
|
-
throw MVC.isTypeof(Type) && Type.global
|
|
1270
|
-
? Oops$3.DoesNotExist(Type.name)
|
|
1271
|
-
: Oops$3.NotFound(Type.name);
|
|
1272
|
-
return instance;
|
|
1273
1263
|
}
|
|
1274
1264
|
|
|
1275
|
-
const
|
|
1276
|
-
|
|
1277
|
-
AmbientRequired: (requested, requester) => `Attempted to find an instance of ${requested} in context. It is required by ${requester}, but one could not be found.`
|
|
1278
|
-
});
|
|
1279
|
-
const Pending = new WeakMap();
|
|
1280
|
-
const Applied = new WeakMap();
|
|
1281
|
-
function getContextForGetInstruction(type, relativeTo, required) {
|
|
1282
|
-
let item = getParent(type, relativeTo);
|
|
1283
|
-
return (refresh) => {
|
|
1284
|
-
if (item)
|
|
1285
|
-
return item;
|
|
1286
|
-
findRelative(relativeTo, type, got => {
|
|
1287
|
-
if (got) {
|
|
1288
|
-
item = got;
|
|
1289
|
-
refresh(got);
|
|
1290
|
-
}
|
|
1291
|
-
else if (required)
|
|
1292
|
-
throw Oops$2.AmbientRequired(type.name, relativeTo);
|
|
1293
|
-
});
|
|
1294
|
-
};
|
|
1295
|
-
}
|
|
1296
|
-
function findRelative(from, type, callback) {
|
|
1297
|
-
if (MVC.isTypeof(type) && type.global)
|
|
1298
|
-
callback(Global$1.get(type));
|
|
1299
|
-
else if (from.constructor.global)
|
|
1300
|
-
throw Oops$2.NotAllowed(from, type.name);
|
|
1301
|
-
else
|
|
1302
|
-
getPending(from).push(context => {
|
|
1303
|
-
callback(context.get(type));
|
|
1304
|
-
});
|
|
1305
|
-
}
|
|
1306
|
-
function usePeerContext(subject) {
|
|
1307
|
-
if (Applied.has(subject)) {
|
|
1308
|
-
if (Applied.get(subject))
|
|
1309
|
-
useLookup();
|
|
1310
|
-
return;
|
|
1311
|
-
}
|
|
1312
|
-
const pending = Pending.get(subject);
|
|
1313
|
-
if (pending) {
|
|
1314
|
-
const local = useLookup();
|
|
1315
|
-
for (const init of pending)
|
|
1316
|
-
init(local);
|
|
1317
|
-
Pending.delete(subject);
|
|
1318
|
-
}
|
|
1319
|
-
Applied.set(subject, !!pending);
|
|
1320
|
-
}
|
|
1321
|
-
function getPending(subject) {
|
|
1322
|
-
let pending = Pending.get(subject);
|
|
1323
|
-
if (!pending)
|
|
1324
|
-
Pending.set(subject, pending = []);
|
|
1325
|
-
return pending;
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
function useModel(source, arg1, arg2) {
|
|
1329
|
-
const instance = React__default["default"].useMemo(() => {
|
|
1330
|
-
const callback = arg2 || arg1;
|
|
1331
|
-
const instance = Model.isTypeof(source)
|
|
1332
|
-
? new source()
|
|
1333
|
-
: source();
|
|
1334
|
-
control(instance);
|
|
1335
|
-
if (typeof callback == "function")
|
|
1336
|
-
callback(instance);
|
|
1337
|
-
return instance;
|
|
1338
|
-
}, []);
|
|
1339
|
-
usePeerContext(instance);
|
|
1340
|
-
if (Array.isArray(arg1)) {
|
|
1341
|
-
const update = React__default["default"].useState(0)[1];
|
|
1342
|
-
React__default["default"].useLayoutEffect(() => {
|
|
1343
|
-
if (arg1.length && instance instanceof Model)
|
|
1344
|
-
instance.on(arg1, () => update(x => x + 1));
|
|
1345
|
-
return () => {
|
|
1346
|
-
if (Model.isTypeof(source))
|
|
1347
|
-
instance.end();
|
|
1348
|
-
};
|
|
1349
|
-
}, []);
|
|
1350
|
-
return instance;
|
|
1351
|
-
}
|
|
1352
|
-
const state = React__default["default"].useState(0);
|
|
1353
|
-
const local = React__default["default"].useMemo(() => {
|
|
1354
|
-
const refresh = state[1].bind(null, x => x + 1);
|
|
1355
|
-
return new Subscriber(control(instance), () => refresh);
|
|
1356
|
-
}, []);
|
|
1357
|
-
if (typeof arg1 == "object")
|
|
1358
|
-
local.apply(arg1, arg2);
|
|
1359
|
-
React__default["default"].useLayoutEffect(() => {
|
|
1360
|
-
local.commit();
|
|
1361
|
-
return () => {
|
|
1362
|
-
local.release();
|
|
1363
|
-
if (Model.isTypeof(source))
|
|
1364
|
-
instance.end();
|
|
1365
|
-
};
|
|
1366
|
-
}, []);
|
|
1367
|
-
return local.proxy;
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
|
-
function useTap(source, arg1, arg2) {
|
|
1371
|
-
const instance = typeof source == "object"
|
|
1372
|
-
? source
|
|
1373
|
-
: "get" in source
|
|
1374
|
-
? source.get()
|
|
1375
|
-
: source();
|
|
1376
|
-
const deps = [uid(instance)];
|
|
1377
|
-
const state = React__default["default"].useState(0);
|
|
1378
|
-
const local = React__default["default"].useMemo(() => {
|
|
1379
|
-
const refresh = state[1].bind(null, x => x + 1);
|
|
1380
|
-
const controller = control(instance);
|
|
1381
|
-
if (typeof arg1 != "function")
|
|
1382
|
-
return new Subscriber(controller, () => refresh, arg1);
|
|
1383
|
-
const sub = new Subscriber(controller, () => update);
|
|
1384
|
-
const spy = sub.proxy;
|
|
1385
|
-
let make = () => arg1.call(spy, spy, forceUpdate);
|
|
1386
|
-
function forceUpdate(passthru) {
|
|
1387
|
-
if (typeof passthru == "function")
|
|
1388
|
-
passthru = passthru();
|
|
1389
|
-
if (make)
|
|
1390
|
-
reassign(make());
|
|
1391
|
-
else
|
|
1392
|
-
refresh();
|
|
1393
|
-
if (passthru)
|
|
1394
|
-
return passthru.finally(refresh);
|
|
1395
|
-
}
|
|
1396
|
-
function reassign(next) {
|
|
1397
|
-
value = next;
|
|
1398
|
-
if (retry) {
|
|
1399
|
-
retry();
|
|
1400
|
-
retry = undefined;
|
|
1401
|
-
}
|
|
1402
|
-
else
|
|
1403
|
-
refresh();
|
|
1404
|
-
}
|
|
1405
|
-
let retry;
|
|
1406
|
-
let update;
|
|
1407
|
-
let value = make();
|
|
1408
|
-
if (value === null) {
|
|
1409
|
-
sub.watch.clear();
|
|
1410
|
-
make = undefined;
|
|
1411
|
-
return;
|
|
1412
|
-
}
|
|
1413
|
-
if (typeof value == "function") {
|
|
1414
|
-
const get = value;
|
|
1415
|
-
sub.watch.clear();
|
|
1416
|
-
arg1 = () => get();
|
|
1417
|
-
value = get();
|
|
1418
|
-
}
|
|
1419
|
-
if (value instanceof Promise) {
|
|
1420
|
-
value.then(reassign);
|
|
1421
|
-
value = undefined;
|
|
1422
|
-
}
|
|
1423
|
-
else {
|
|
1424
|
-
sub.commit();
|
|
1425
|
-
update = () => {
|
|
1426
|
-
const next = make();
|
|
1427
|
-
if (notEqual(value, next))
|
|
1428
|
-
reassign(next);
|
|
1429
|
-
};
|
|
1430
|
-
}
|
|
1431
|
-
defineProperty(sub, "proxy", {
|
|
1432
|
-
get() {
|
|
1433
|
-
if (value !== undefined)
|
|
1434
|
-
return value;
|
|
1435
|
-
if (arg2)
|
|
1436
|
-
throw new Promise(res => retry = res);
|
|
1437
|
-
return null;
|
|
1438
|
-
}
|
|
1439
|
-
});
|
|
1440
|
-
return sub;
|
|
1441
|
-
}, deps);
|
|
1442
|
-
if (!local)
|
|
1443
|
-
return null;
|
|
1444
|
-
React__default["default"].useLayoutEffect(() => {
|
|
1445
|
-
local.commit();
|
|
1446
|
-
return () => local.release();
|
|
1447
|
-
}, deps);
|
|
1448
|
-
return local.proxy;
|
|
1449
|
-
}
|
|
1450
|
-
/** Values are not equal for purposes of a refresh. */
|
|
1451
|
-
const notEqual = (a, b) => (b !== a && (!Array.isArray(a) ||
|
|
1452
|
-
!Array.isArray(b) ||
|
|
1453
|
-
a.length !== b.length ||
|
|
1454
|
-
a.some((x, i) => x !== b[i])));
|
|
1455
|
-
|
|
1456
|
-
class MVC extends Model {
|
|
1457
|
-
end(force) {
|
|
1458
|
-
const type = this.constructor;
|
|
1459
|
-
if (type.keepAlive && !force)
|
|
1460
|
-
return false;
|
|
1461
|
-
super.end();
|
|
1462
|
-
Global$1.delete(this);
|
|
1463
|
-
return true;
|
|
1464
|
-
}
|
|
1465
|
-
static new(...args) {
|
|
1466
|
-
const exists = Global$1.get(this);
|
|
1467
|
-
if (exists)
|
|
1468
|
-
if (this.keepAlive)
|
|
1469
|
-
return exists;
|
|
1470
|
-
else
|
|
1471
|
-
throw Oops$3.AlreadyExists(this.name);
|
|
1472
|
-
const instance = super.new(...args);
|
|
1473
|
-
if (this.global)
|
|
1474
|
-
Global$1.add(instance);
|
|
1475
|
-
return instance;
|
|
1476
|
-
}
|
|
1477
|
-
static get(arg1, arg2) {
|
|
1478
|
-
const required = arg1 === undefined || arg1 === true;
|
|
1479
|
-
const instance = useContext(this, required);
|
|
1480
|
-
if (typeof arg1 === "function" && instance)
|
|
1481
|
-
callback(arg1);
|
|
1482
|
-
else if (arg2)
|
|
1483
|
-
callback(arg2);
|
|
1484
|
-
return instance;
|
|
1485
|
-
function callback(effect) {
|
|
1486
|
-
try {
|
|
1487
|
-
React__default["default"].useLayoutEffect(() => effect(instance), []);
|
|
1488
|
-
}
|
|
1489
|
-
catch (err) {
|
|
1490
|
-
if (instance)
|
|
1491
|
-
instance.on(effect, []);
|
|
1492
|
-
else
|
|
1493
|
-
effect(undefined);
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1497
|
-
static tap(arg1, arg2) {
|
|
1498
|
-
return useTap(this, arg1, arg2);
|
|
1499
|
-
}
|
|
1500
|
-
static use(a, b) {
|
|
1501
|
-
return useModel(this, a, b);
|
|
1502
|
-
}
|
|
1503
|
-
static meta(arg1, arg2) {
|
|
1504
|
-
return useTap(() => this, arg1, arg2);
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
FindInstruction.set(MVC, getContextForGetInstruction);
|
|
1508
|
-
|
|
1509
|
-
const Oops$1 = issues({
|
|
1510
|
-
BadProps: () => `Provider expects either a render function, 'get' or 'has' props.`
|
|
1511
|
-
});
|
|
1512
|
-
function Consumer(props) {
|
|
1513
|
-
const { get, has, children, for: type } = props;
|
|
1514
|
-
if (typeof children == "function")
|
|
1515
|
-
return children(useTap(type));
|
|
1516
|
-
const callback = has || get;
|
|
1517
|
-
if (typeof callback == "function")
|
|
1518
|
-
callback(useContext(type, !!has));
|
|
1519
|
-
else
|
|
1520
|
-
throw Oops$1.BadProps();
|
|
1521
|
-
return null;
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
const Oops = issues({
|
|
1525
|
-
NoType: () => "Provider 'for' prop must be Model, typeof Model or a collection of them."
|
|
1526
|
-
});
|
|
1527
|
-
function Provider(props) {
|
|
1528
|
-
const context = useNewContext(props.for, props.use);
|
|
1529
|
-
return (React__default["default"].createElement(LookupContext.Provider, { value: context }, props.fallback === false
|
|
1530
|
-
? props.children
|
|
1531
|
-
: (React__default["default"].createElement(React.Suspense, { fallback: props.fallback || null }, props.children))));
|
|
1532
|
-
}
|
|
1533
|
-
function useNewContext(include, assign) {
|
|
1534
|
-
const init = new Set();
|
|
1535
|
-
const ambient = useLookup();
|
|
1536
|
-
const context = React__default["default"].useMemo(() => {
|
|
1537
|
-
if (!include)
|
|
1538
|
-
throw Oops.NoType();
|
|
1539
|
-
return ambient.push();
|
|
1540
|
-
}, []);
|
|
1541
|
-
function register(key, input) {
|
|
1542
|
-
let instance;
|
|
1543
|
-
if (MVC.isTypeof(input) && input.global)
|
|
1544
|
-
instance = input.new();
|
|
1545
|
-
else if (context.register.get(key) === input)
|
|
1546
|
-
instance = typeof input == "object"
|
|
1547
|
-
? input
|
|
1548
|
-
: context.get(input);
|
|
1549
|
-
else
|
|
1550
|
-
instance = context.add(input, key);
|
|
1551
|
-
init.add(instance);
|
|
1552
|
-
if (assign)
|
|
1553
|
-
assignWeak(instance, assign);
|
|
1554
|
-
}
|
|
1555
|
-
if (typeof include == "function" || include instanceof Model)
|
|
1556
|
-
register(0, include);
|
|
1557
|
-
else
|
|
1558
|
-
entries(include).forEach(e => register(...e));
|
|
1559
|
-
for (const instance of init) {
|
|
1560
|
-
control(instance).state.forEach(value => {
|
|
1561
|
-
// TODO: should this run repeatedly?
|
|
1562
|
-
if (Parent.get(value) === instance) {
|
|
1563
|
-
context.add(value);
|
|
1564
|
-
init.add(value);
|
|
1565
|
-
}
|
|
1566
|
-
});
|
|
1567
|
-
for (const apply of getPending(instance))
|
|
1568
|
-
apply(context);
|
|
1569
|
-
// TODO: add test to validate this.
|
|
1570
|
-
init.delete(instance);
|
|
1571
|
-
}
|
|
1572
|
-
React__default["default"].useLayoutEffect(() => () => context.pop(), []);
|
|
1573
|
-
return context;
|
|
1574
|
-
}
|
|
1575
|
-
|
|
1576
|
-
class Global extends MVC {
|
|
1577
|
-
}
|
|
1578
|
-
Global.global = true;
|
|
1579
|
-
Global.keepAlive = true;
|
|
1580
|
-
|
|
1581
|
-
const LOCAL = "$debug local";
|
|
1582
|
-
const STATE = "$debug state";
|
|
1583
|
-
const UPDATE = "$debug update";
|
|
1584
|
-
const CONTROL = "$debug controller";
|
|
1585
|
-
defineProperties(Model.prototype, {
|
|
1586
|
-
[CONTROL]: {
|
|
1587
|
-
get() {
|
|
1588
|
-
return controller(this);
|
|
1589
|
-
}
|
|
1590
|
-
},
|
|
1591
|
-
[LOCAL]: {
|
|
1592
|
-
get() {
|
|
1593
|
-
return subscriber(this);
|
|
1594
|
-
}
|
|
1595
|
-
},
|
|
1596
|
-
[STATE]: {
|
|
1597
|
-
get() {
|
|
1598
|
-
const { state } = controller(this);
|
|
1599
|
-
const output = {};
|
|
1600
|
-
state.forEach((value, key) => output[key] = value);
|
|
1601
|
-
return output;
|
|
1602
|
-
}
|
|
1603
|
-
},
|
|
1604
|
-
[UPDATE]: {
|
|
1605
|
-
get() {
|
|
1606
|
-
return (subscriber(this) || controller(this)).latest;
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
});
|
|
1610
|
-
const Debug = {
|
|
1611
|
-
CONTROL,
|
|
1612
|
-
LOCAL,
|
|
1613
|
-
STATE,
|
|
1614
|
-
UPDATE
|
|
1265
|
+
const Internal = {
|
|
1266
|
+
getParent
|
|
1615
1267
|
};
|
|
1616
1268
|
|
|
1617
|
-
exports.
|
|
1269
|
+
exports.Control = Control;
|
|
1618
1270
|
exports.Debug = Debug;
|
|
1619
|
-
exports.
|
|
1620
|
-
exports.
|
|
1621
|
-
exports.
|
|
1622
|
-
exports.
|
|
1271
|
+
exports.Internal = Internal;
|
|
1272
|
+
exports.Model = Model;
|
|
1273
|
+
exports.Register = Register;
|
|
1274
|
+
exports.Subscriber = Subscriber;
|
|
1623
1275
|
exports.add = add;
|
|
1624
|
-
exports["default"] =
|
|
1276
|
+
exports["default"] = Model;
|
|
1625
1277
|
exports.get = get;
|
|
1626
1278
|
exports.ref = ref;
|
|
1627
1279
|
exports.run = run;
|