@expressive/mvc 0.11.1 → 0.13.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 +9 -23
- package/lib/index.esm.js +215 -203
- package/lib/index.js +214 -202
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -9,8 +9,17 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
9
9
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
10
10
|
|
|
11
11
|
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const UID_CACHE = new WeakMap();
|
|
13
|
+
function assignWeak(into, from) {
|
|
14
|
+
for (const K in from)
|
|
15
|
+
if (K in into)
|
|
16
|
+
into[K] = from[K];
|
|
17
|
+
}
|
|
18
|
+
function uid(object) {
|
|
19
|
+
let uid = UID_CACHE.get(object);
|
|
20
|
+
if (!uid)
|
|
21
|
+
UID_CACHE.set(object, uid = Math.random());
|
|
22
|
+
return uid;
|
|
14
23
|
}
|
|
15
24
|
|
|
16
25
|
class Issue extends Error {
|
|
@@ -169,7 +178,7 @@ const Oops$d = issues({
|
|
|
169
178
|
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
170
179
|
});
|
|
171
180
|
function createEffect(model, callback, keys) {
|
|
172
|
-
return
|
|
181
|
+
return control(model, controller => {
|
|
173
182
|
let unSet;
|
|
174
183
|
let busy = false;
|
|
175
184
|
function effect(value) {
|
|
@@ -194,7 +203,7 @@ function createEffect(model, callback, keys) {
|
|
|
194
203
|
}
|
|
195
204
|
if (Array.isArray(keys)) {
|
|
196
205
|
invoke();
|
|
197
|
-
return
|
|
206
|
+
return controller.addListener(key => {
|
|
198
207
|
if (key === null) {
|
|
199
208
|
if (!keys.length)
|
|
200
209
|
invoke();
|
|
@@ -203,7 +212,7 @@ function createEffect(model, callback, keys) {
|
|
|
203
212
|
return invoke;
|
|
204
213
|
});
|
|
205
214
|
}
|
|
206
|
-
const sub =
|
|
215
|
+
const sub = controller.subscribe(() => invoke);
|
|
207
216
|
model = sub.proxy;
|
|
208
217
|
invoke();
|
|
209
218
|
return sub.commit();
|
|
@@ -235,13 +244,13 @@ const Oops$c = issues({
|
|
|
235
244
|
function addEventListener(source, arg1, arg2, arg3) {
|
|
236
245
|
if (typeof arg1 == "string")
|
|
237
246
|
arg1 = [arg1];
|
|
238
|
-
return
|
|
247
|
+
return control(source, controller => {
|
|
239
248
|
for (const key of arg1)
|
|
240
249
|
try {
|
|
241
250
|
void source[key];
|
|
242
251
|
}
|
|
243
252
|
catch (e) { }
|
|
244
|
-
const removeListener =
|
|
253
|
+
const removeListener = controller.addListener(key => {
|
|
245
254
|
if (!key && !arg1.length)
|
|
246
255
|
arg2.call(source, []);
|
|
247
256
|
if (arg1.includes(key)) {
|
|
@@ -264,8 +273,8 @@ function awaitUpdate(source, arg1, arg2) {
|
|
|
264
273
|
removeListener();
|
|
265
274
|
reject(Oops$c.Timeout(k, message));
|
|
266
275
|
};
|
|
267
|
-
const removeListener =
|
|
268
|
-
const pending =
|
|
276
|
+
const removeListener = control(source, controller => {
|
|
277
|
+
const pending = controller.frame;
|
|
269
278
|
if (keys === null) {
|
|
270
279
|
if (pending.size)
|
|
271
280
|
reject(Oops$c.StrictNoUpdate());
|
|
@@ -292,8 +301,8 @@ function awaitUpdate(source, arg1, arg2) {
|
|
|
292
301
|
return;
|
|
293
302
|
}
|
|
294
303
|
else
|
|
295
|
-
|
|
296
|
-
return
|
|
304
|
+
controller.waiting.add(resolve);
|
|
305
|
+
return controller.addListener(key => {
|
|
297
306
|
if (!key) {
|
|
298
307
|
if (keys && !keys.length)
|
|
299
308
|
resolve([]);
|
|
@@ -302,7 +311,7 @@ function awaitUpdate(source, arg1, arg2) {
|
|
|
302
311
|
}
|
|
303
312
|
else if (!keys || keys.includes(key)) {
|
|
304
313
|
removeListener();
|
|
305
|
-
return keys => resolve(single ?
|
|
314
|
+
return keys => resolve(single ? controller.state.get(key) : keys);
|
|
306
315
|
}
|
|
307
316
|
});
|
|
308
317
|
});
|
|
@@ -319,35 +328,6 @@ class Subscriber {
|
|
|
319
328
|
this.active = false;
|
|
320
329
|
this.dependant = new Set();
|
|
321
330
|
this.watch = new Map();
|
|
322
|
-
this.commit = () => {
|
|
323
|
-
const release = this.parent.addListener(this.event);
|
|
324
|
-
this.active = true;
|
|
325
|
-
this.dependant.forEach(x => x.commit());
|
|
326
|
-
return this.release = () => {
|
|
327
|
-
this.dependant.forEach(x => x.release());
|
|
328
|
-
release();
|
|
329
|
-
};
|
|
330
|
-
};
|
|
331
|
-
this.event = (key) => {
|
|
332
|
-
if (!this.active)
|
|
333
|
-
return;
|
|
334
|
-
const { parent, watch } = this;
|
|
335
|
-
const handler = watch.get(key);
|
|
336
|
-
let notify;
|
|
337
|
-
if (typeof handler == "function") {
|
|
338
|
-
const callback = handler();
|
|
339
|
-
if (callback === true)
|
|
340
|
-
notify = this.onUpdate(key, parent);
|
|
341
|
-
}
|
|
342
|
-
else if (handler === true)
|
|
343
|
-
notify = this.onUpdate(key, parent);
|
|
344
|
-
if (!notify)
|
|
345
|
-
return;
|
|
346
|
-
parent.waiting.add(update => {
|
|
347
|
-
this.latest = update.filter(k => watch.has(k));
|
|
348
|
-
});
|
|
349
|
-
parent.waiting.add(notify);
|
|
350
|
-
};
|
|
351
331
|
const proxy = create(parent.subject);
|
|
352
332
|
const reset = () => this.latest = undefined;
|
|
353
333
|
REGISTER$1.set(proxy, this);
|
|
@@ -359,28 +339,45 @@ class Subscriber {
|
|
|
359
339
|
}
|
|
360
340
|
});
|
|
361
341
|
}
|
|
362
|
-
static get(from) {
|
|
363
|
-
return REGISTER$1.get(from);
|
|
364
|
-
}
|
|
365
342
|
get using() {
|
|
366
343
|
return Array.from(this.watch.keys());
|
|
367
344
|
}
|
|
368
|
-
assign(apply, keys) {
|
|
369
|
-
const { waiting, subject } = this.parent;
|
|
370
|
-
this.active = false;
|
|
371
|
-
if (typeof keys !== "object")
|
|
372
|
-
keys = getOwnPropertyNames(subject);
|
|
373
|
-
for (const key of keys)
|
|
374
|
-
if (key in apply)
|
|
375
|
-
subject[key] = apply[key];
|
|
376
|
-
waiting.add(() => this.active = true);
|
|
377
|
-
}
|
|
378
345
|
add(key, value) {
|
|
379
346
|
if (value !== undefined)
|
|
380
347
|
this.watch.set(key, value);
|
|
381
348
|
else if (!this.watch.has(key))
|
|
382
349
|
this.watch.set(key, true);
|
|
383
350
|
}
|
|
351
|
+
commit() {
|
|
352
|
+
const release = this.parent.addListener(key => {
|
|
353
|
+
if (this.active)
|
|
354
|
+
this.onEvent(key);
|
|
355
|
+
});
|
|
356
|
+
this.active = true;
|
|
357
|
+
this.dependant.forEach(x => x.commit());
|
|
358
|
+
return this.release = () => {
|
|
359
|
+
this.dependant.forEach(x => x.release());
|
|
360
|
+
release();
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
onEvent(key) {
|
|
364
|
+
const { parent, watch } = this;
|
|
365
|
+
let handler = watch.get(key);
|
|
366
|
+
if (typeof handler == "function")
|
|
367
|
+
handler = handler();
|
|
368
|
+
if (handler) {
|
|
369
|
+
const notify = this.onUpdate(key, parent);
|
|
370
|
+
if (notify) {
|
|
371
|
+
parent.waiting.add(update => {
|
|
372
|
+
this.latest = update.filter(k => watch.has(k));
|
|
373
|
+
});
|
|
374
|
+
parent.waiting.add(notify);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function subscriber(from) {
|
|
380
|
+
return REGISTER$1.get(from);
|
|
384
381
|
}
|
|
385
382
|
|
|
386
383
|
const Oops$b = issues({
|
|
@@ -400,7 +397,7 @@ class Model {
|
|
|
400
397
|
return addEventListener(this.is, arg1, arg2, arg3);
|
|
401
398
|
}
|
|
402
399
|
get(arg1, arg2) {
|
|
403
|
-
const { state } =
|
|
400
|
+
const { state } = control(this);
|
|
404
401
|
const extract = typeof arg1 == "string"
|
|
405
402
|
? () => state.get(arg1)
|
|
406
403
|
: () => {
|
|
@@ -417,19 +414,20 @@ class Model {
|
|
|
417
414
|
return this.on(arg1, timeout).then(extract);
|
|
418
415
|
}
|
|
419
416
|
set(arg1, arg2) {
|
|
420
|
-
const
|
|
417
|
+
const controller = control(this);
|
|
418
|
+
const { state } = controller;
|
|
421
419
|
if (typeof arg1 == "object")
|
|
422
420
|
for (const key in arg1) {
|
|
423
|
-
if (arg2 === true || (arg2 ? arg2.includes(key) :
|
|
424
|
-
|
|
425
|
-
|
|
421
|
+
if (arg2 === true || (arg2 ? arg2.includes(key) : state.has(key))) {
|
|
422
|
+
state.set(key, arg1[key]);
|
|
423
|
+
controller.update(key);
|
|
426
424
|
}
|
|
427
425
|
}
|
|
428
426
|
else if (typeof arg1 == "string") {
|
|
429
|
-
|
|
427
|
+
controller.update(arg1);
|
|
430
428
|
if (1 in arguments) {
|
|
431
|
-
if (
|
|
432
|
-
|
|
429
|
+
if (state.has(arg1))
|
|
430
|
+
state.set(arg1, arg2);
|
|
433
431
|
else if (arg1 in this) {
|
|
434
432
|
const method = this[arg1];
|
|
435
433
|
if (typeof method == "function")
|
|
@@ -441,7 +439,7 @@ class Model {
|
|
|
441
439
|
then: (callback) => {
|
|
442
440
|
if (!callback)
|
|
443
441
|
throw Oops$b.NoChaining();
|
|
444
|
-
|
|
442
|
+
controller.waiting.add(callback);
|
|
445
443
|
}
|
|
446
444
|
};
|
|
447
445
|
}
|
|
@@ -449,7 +447,7 @@ class Model {
|
|
|
449
447
|
* Clean up side effects and mark this instance for garbage-collection.
|
|
450
448
|
*/
|
|
451
449
|
end() {
|
|
452
|
-
|
|
450
|
+
control(this).clear();
|
|
453
451
|
}
|
|
454
452
|
/**
|
|
455
453
|
* Creates a new instance of this controller.
|
|
@@ -460,7 +458,7 @@ class Model {
|
|
|
460
458
|
*/
|
|
461
459
|
static new(...args) {
|
|
462
460
|
const instance = new this(...args);
|
|
463
|
-
|
|
461
|
+
control(instance);
|
|
464
462
|
return instance;
|
|
465
463
|
}
|
|
466
464
|
/**
|
|
@@ -515,7 +513,7 @@ class Control {
|
|
|
515
513
|
enumerable: false,
|
|
516
514
|
set: this.ref(key),
|
|
517
515
|
get() {
|
|
518
|
-
const sub =
|
|
516
|
+
const sub = subscriber(this);
|
|
519
517
|
if (sub)
|
|
520
518
|
sub.add(key);
|
|
521
519
|
return state.get(key);
|
|
@@ -575,34 +573,34 @@ class Control {
|
|
|
575
573
|
this.followers.clear();
|
|
576
574
|
listeners.forEach(x => x(null, this));
|
|
577
575
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
}
|
|
597
|
-
control.state = new Map();
|
|
598
|
-
for (const key in subject)
|
|
599
|
-
control.watch(key);
|
|
600
|
-
control.waiting = new Set();
|
|
601
|
-
for (const cb of waiting)
|
|
602
|
-
cb([]);
|
|
576
|
+
}
|
|
577
|
+
function controller(from) {
|
|
578
|
+
if ("is" in from)
|
|
579
|
+
from = from.is;
|
|
580
|
+
return REGISTER.get(from);
|
|
581
|
+
}
|
|
582
|
+
function control(subject, cb) {
|
|
583
|
+
const control = controller(subject) || new Control(subject);
|
|
584
|
+
if (!control.state) {
|
|
585
|
+
const { waiting } = control;
|
|
586
|
+
if (cb) {
|
|
587
|
+
let callback;
|
|
588
|
+
waiting.add(() => {
|
|
589
|
+
callback = cb(control);
|
|
590
|
+
});
|
|
591
|
+
return () => {
|
|
592
|
+
if (callback)
|
|
593
|
+
callback();
|
|
594
|
+
};
|
|
603
595
|
}
|
|
604
|
-
|
|
596
|
+
control.state = new Map();
|
|
597
|
+
for (const key in subject)
|
|
598
|
+
control.watch(key);
|
|
599
|
+
control.waiting = new Set();
|
|
600
|
+
for (const cb of waiting)
|
|
601
|
+
cb([]);
|
|
605
602
|
}
|
|
603
|
+
return cb ? cb(control) : control;
|
|
606
604
|
}
|
|
607
605
|
|
|
608
606
|
const Parent = new WeakMap();
|
|
@@ -621,8 +619,8 @@ function getRecursive(key, from) {
|
|
|
621
619
|
if (reset)
|
|
622
620
|
reset();
|
|
623
621
|
const value = state.get(key);
|
|
624
|
-
if (
|
|
625
|
-
const child =
|
|
622
|
+
if (value && controller(value)) {
|
|
623
|
+
const child = control(value).subscribe(local.onUpdate);
|
|
626
624
|
if (local.active)
|
|
627
625
|
child.commit();
|
|
628
626
|
local.dependant.add(child);
|
|
@@ -642,24 +640,24 @@ function getRecursive(key, from) {
|
|
|
642
640
|
return context.get(local);
|
|
643
641
|
};
|
|
644
642
|
}
|
|
645
|
-
function setRecursive(
|
|
646
|
-
const { state, subject } =
|
|
643
|
+
function setRecursive(controller, key, initial) {
|
|
644
|
+
const { state, subject } = controller;
|
|
647
645
|
const Type = initial.constructor;
|
|
648
646
|
let get;
|
|
649
647
|
const onUpdate = (next) => {
|
|
650
648
|
state.set(key, next);
|
|
651
649
|
if (!(next instanceof Type))
|
|
652
650
|
throw Oops$a.BadAssignment(`${subject}.${key}`, Type.name, String(next));
|
|
653
|
-
get = getRecursive(key,
|
|
651
|
+
get = getRecursive(key, controller);
|
|
654
652
|
Parent.set(next, subject);
|
|
655
|
-
|
|
653
|
+
control(next);
|
|
656
654
|
return true;
|
|
657
655
|
};
|
|
658
656
|
onUpdate(initial);
|
|
659
657
|
defineProperty(subject, key, {
|
|
660
|
-
set:
|
|
658
|
+
set: controller.ref(key, onUpdate),
|
|
661
659
|
get() {
|
|
662
|
-
const local =
|
|
660
|
+
const local = subscriber(this);
|
|
663
661
|
if (local)
|
|
664
662
|
local.add(key);
|
|
665
663
|
return get(local);
|
|
@@ -707,7 +705,7 @@ function add(instruction, label) {
|
|
|
707
705
|
get() {
|
|
708
706
|
if (!state.has(key) && shouldSuspend)
|
|
709
707
|
throw suspend(control, key);
|
|
710
|
-
const local =
|
|
708
|
+
const local = subscriber(this);
|
|
711
709
|
if (local)
|
|
712
710
|
local.add(key);
|
|
713
711
|
return onGet
|
|
@@ -778,13 +776,13 @@ function run(task) {
|
|
|
778
776
|
const Oops$8 = issues({
|
|
779
777
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
780
778
|
});
|
|
781
|
-
function factoryMode(self,
|
|
779
|
+
function factoryMode(self, value, key, required) {
|
|
782
780
|
const { subject, state } = self;
|
|
783
781
|
let pending;
|
|
784
782
|
let error;
|
|
785
|
-
if (
|
|
783
|
+
if (value instanceof Promise) {
|
|
786
784
|
state.set(key, undefined);
|
|
787
|
-
pending =
|
|
785
|
+
pending = value
|
|
788
786
|
.catch(err => error = err)
|
|
789
787
|
.then(val => {
|
|
790
788
|
state.set(key, val);
|
|
@@ -795,7 +793,8 @@ function factoryMode(self, output, key, required) {
|
|
|
795
793
|
self.update(key);
|
|
796
794
|
});
|
|
797
795
|
}
|
|
798
|
-
|
|
796
|
+
else
|
|
797
|
+
state.set(key, value);
|
|
799
798
|
const suspend = () => {
|
|
800
799
|
if (required === false)
|
|
801
800
|
return undefined;
|
|
@@ -837,7 +836,7 @@ function get(arg0, arg1, arg2) {
|
|
|
837
836
|
let source = this;
|
|
838
837
|
let setter;
|
|
839
838
|
if (typeof arg0 == "function") {
|
|
840
|
-
|
|
839
|
+
let result = mayRetry(arg0.bind(subject, key, subject));
|
|
841
840
|
if (typeof result == "function")
|
|
842
841
|
setter = result;
|
|
843
842
|
else {
|
|
@@ -851,7 +850,7 @@ function get(arg0, arg1, arg2) {
|
|
|
851
850
|
}
|
|
852
851
|
else if (typeof arg1 == "function") {
|
|
853
852
|
// replace source controller in-case it is different
|
|
854
|
-
source =
|
|
853
|
+
source = control(arg0);
|
|
855
854
|
setter = arg1;
|
|
856
855
|
}
|
|
857
856
|
else
|
|
@@ -881,7 +880,7 @@ function ref(arg, mapper) {
|
|
|
881
880
|
if (typeof arg != "object")
|
|
882
881
|
value = createRef(this, key, arg);
|
|
883
882
|
else
|
|
884
|
-
|
|
883
|
+
control(arg).state.forEach((_val, key) => {
|
|
885
884
|
defineProperty(value, key, mapper ? {
|
|
886
885
|
configurable: true,
|
|
887
886
|
get() {
|
|
@@ -1092,7 +1091,7 @@ function use$1(input, argument) {
|
|
|
1092
1091
|
if (next) {
|
|
1093
1092
|
get = getRecursive(key, this);
|
|
1094
1093
|
Parent.set(next, subject);
|
|
1095
|
-
|
|
1094
|
+
control(next);
|
|
1096
1095
|
}
|
|
1097
1096
|
if (typeof argument == "function")
|
|
1098
1097
|
argument(next);
|
|
@@ -1172,9 +1171,6 @@ class Lookup {
|
|
|
1172
1171
|
constructor() {
|
|
1173
1172
|
this.table = new Map();
|
|
1174
1173
|
}
|
|
1175
|
-
get local() {
|
|
1176
|
-
return unique(getOwnPropertySymbols(this).map(symbol => this[symbol]));
|
|
1177
|
-
}
|
|
1178
1174
|
key(T) {
|
|
1179
1175
|
let key = this.table.get(T);
|
|
1180
1176
|
if (!key) {
|
|
@@ -1183,8 +1179,21 @@ class Lookup {
|
|
|
1183
1179
|
}
|
|
1184
1180
|
return key;
|
|
1185
1181
|
}
|
|
1186
|
-
get(
|
|
1187
|
-
return this[this.key(
|
|
1182
|
+
get(Type) {
|
|
1183
|
+
return this[this.key(Type)];
|
|
1184
|
+
}
|
|
1185
|
+
has(key, input, callback) {
|
|
1186
|
+
if (MVC.isTypeof(input) && input.global)
|
|
1187
|
+
return input.new();
|
|
1188
|
+
if (this.register.get(key) === input)
|
|
1189
|
+
return typeof input == "object"
|
|
1190
|
+
? input
|
|
1191
|
+
: this.get(input);
|
|
1192
|
+
const instance = this.add(input);
|
|
1193
|
+
this.register.set(key, input);
|
|
1194
|
+
if (callback)
|
|
1195
|
+
callback(instance);
|
|
1196
|
+
return instance;
|
|
1188
1197
|
}
|
|
1189
1198
|
add(input) {
|
|
1190
1199
|
let writable = true;
|
|
@@ -1192,7 +1201,7 @@ class Lookup {
|
|
|
1192
1201
|
let I;
|
|
1193
1202
|
if (typeof input == "function") {
|
|
1194
1203
|
T = input;
|
|
1195
|
-
I = input
|
|
1204
|
+
I = new input();
|
|
1196
1205
|
}
|
|
1197
1206
|
else {
|
|
1198
1207
|
I = input;
|
|
@@ -1201,21 +1210,19 @@ class Lookup {
|
|
|
1201
1210
|
}
|
|
1202
1211
|
do {
|
|
1203
1212
|
const key = this.key(T);
|
|
1204
|
-
const conflict = this.hasOwnProperty(key);
|
|
1205
1213
|
defineProperty(this, key, {
|
|
1206
|
-
value: conflict ? null : I,
|
|
1207
1214
|
configurable: true,
|
|
1215
|
+
value: this.hasOwnProperty(key) ? null : I,
|
|
1208
1216
|
writable
|
|
1209
1217
|
});
|
|
1210
1218
|
T = getPrototypeOf(T);
|
|
1211
1219
|
} while (T !== Model);
|
|
1212
|
-
|
|
1213
|
-
if (Parent.get(value) === I)
|
|
1214
|
-
this.add(value);
|
|
1215
|
-
});
|
|
1220
|
+
return I;
|
|
1216
1221
|
}
|
|
1217
1222
|
push() {
|
|
1218
|
-
|
|
1223
|
+
const next = create(this);
|
|
1224
|
+
this.register = new Map();
|
|
1225
|
+
return next;
|
|
1219
1226
|
}
|
|
1220
1227
|
pop() {
|
|
1221
1228
|
const items = new Set();
|
|
@@ -1245,7 +1252,7 @@ const Pending = new WeakMap();
|
|
|
1245
1252
|
const Applied = new WeakMap();
|
|
1246
1253
|
function tap(type, argument) {
|
|
1247
1254
|
return add(function tap(key) {
|
|
1248
|
-
if (type.global)
|
|
1255
|
+
if (MVC.isTypeof(type) && type.global)
|
|
1249
1256
|
return {
|
|
1250
1257
|
recursive: true,
|
|
1251
1258
|
value: type.get()
|
|
@@ -1292,20 +1299,13 @@ function getPending(subject) {
|
|
|
1292
1299
|
return pending;
|
|
1293
1300
|
}
|
|
1294
1301
|
|
|
1295
|
-
function use(init) {
|
|
1296
|
-
const [state, update] = React__default["default"].useState(() => [
|
|
1297
|
-
init(() => update(state.concat()))
|
|
1298
|
-
]);
|
|
1299
|
-
return state[0];
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
1302
|
function useNew(source, arg1, arg2) {
|
|
1303
1303
|
const instance = React__default["default"].useMemo(() => {
|
|
1304
1304
|
const callback = arg2 || arg1;
|
|
1305
1305
|
const instance = Model.isTypeof(source)
|
|
1306
1306
|
? new source()
|
|
1307
1307
|
: source();
|
|
1308
|
-
|
|
1308
|
+
control(instance);
|
|
1309
1309
|
if (typeof callback == "function")
|
|
1310
1310
|
callback(instance);
|
|
1311
1311
|
return instance;
|
|
@@ -1323,9 +1323,22 @@ function useNew(source, arg1, arg2) {
|
|
|
1323
1323
|
}, []);
|
|
1324
1324
|
return instance;
|
|
1325
1325
|
}
|
|
1326
|
-
const
|
|
1327
|
-
|
|
1328
|
-
|
|
1326
|
+
const state = React__default["default"].useState(0);
|
|
1327
|
+
const local = React__default["default"].useMemo(() => {
|
|
1328
|
+
const refresh = state[1].bind(null, x => x + 1);
|
|
1329
|
+
return control(instance).subscribe(() => refresh);
|
|
1330
|
+
}, []);
|
|
1331
|
+
if (typeof arg1 == "object") {
|
|
1332
|
+
const { waiting, subject } = local.parent;
|
|
1333
|
+
let keys = arg2;
|
|
1334
|
+
local.active = false;
|
|
1335
|
+
if (!keys)
|
|
1336
|
+
keys = getOwnPropertyNames(subject);
|
|
1337
|
+
for (const key of keys)
|
|
1338
|
+
if (key in arg1)
|
|
1339
|
+
subject[key] = arg1[key];
|
|
1340
|
+
waiting.add(() => local.active = true);
|
|
1341
|
+
}
|
|
1329
1342
|
React__default["default"].useLayoutEffect(() => {
|
|
1330
1343
|
local.commit();
|
|
1331
1344
|
return () => {
|
|
@@ -1337,9 +1350,17 @@ function useNew(source, arg1, arg2) {
|
|
|
1337
1350
|
return local.proxy;
|
|
1338
1351
|
}
|
|
1339
1352
|
|
|
1340
|
-
function
|
|
1353
|
+
function use(init, deps) {
|
|
1354
|
+
const state = React__default["default"].useState(0);
|
|
1355
|
+
return React__default["default"].useMemo(() => {
|
|
1356
|
+
return init(state[1].bind(null, x => x + 1));
|
|
1357
|
+
}, deps);
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
function useCompute(source, compute, suspend) {
|
|
1361
|
+
const deps = [uid(source)];
|
|
1341
1362
|
const local = use(refresh => {
|
|
1342
|
-
const sub =
|
|
1363
|
+
const sub = control(source).subscribe(() => update);
|
|
1343
1364
|
const spy = sub.proxy;
|
|
1344
1365
|
let value = compute.call(spy, spy);
|
|
1345
1366
|
let update;
|
|
@@ -1388,30 +1409,30 @@ function useValue(source, compute, suspend) {
|
|
|
1388
1409
|
}
|
|
1389
1410
|
});
|
|
1390
1411
|
return sub;
|
|
1391
|
-
});
|
|
1392
|
-
React__default["default"].useLayoutEffect(() => local.release,
|
|
1412
|
+
}, deps);
|
|
1413
|
+
React__default["default"].useLayoutEffect(() => local.release, deps);
|
|
1393
1414
|
return local.proxy;
|
|
1394
1415
|
}
|
|
1395
1416
|
|
|
1396
1417
|
function useTap(source, arg1, arg2) {
|
|
1397
|
-
const instance =
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
const local = use(refresh => (
|
|
1409
|
-
React__default["default"].useLayoutEffect(local.commit,
|
|
1410
|
-
if (
|
|
1418
|
+
const instance = typeof source == "object"
|
|
1419
|
+
? source
|
|
1420
|
+
: "get" in source
|
|
1421
|
+
? source.get()
|
|
1422
|
+
: useContext(source);
|
|
1423
|
+
return typeof arg1 == "function"
|
|
1424
|
+
? useCompute(instance, arg1, arg2)
|
|
1425
|
+
: useSubscribe(instance, arg1, arg2);
|
|
1426
|
+
}
|
|
1427
|
+
function useSubscribe(source, path, expect) {
|
|
1428
|
+
const deps = [uid(source)];
|
|
1429
|
+
const local = use(refresh => (control(source).subscribe(() => refresh)), deps);
|
|
1430
|
+
React__default["default"].useLayoutEffect(() => local.commit(), deps);
|
|
1431
|
+
if (path === undefined)
|
|
1411
1432
|
return local.proxy;
|
|
1412
|
-
const value = local.proxy[
|
|
1413
|
-
if (value === undefined &&
|
|
1414
|
-
throw suspend(local.parent,
|
|
1433
|
+
const value = local.proxy[path];
|
|
1434
|
+
if (value === undefined && expect)
|
|
1435
|
+
throw suspend(local.parent, path);
|
|
1415
1436
|
return value;
|
|
1416
1437
|
}
|
|
1417
1438
|
|
|
@@ -1469,14 +1490,19 @@ class MVC extends Model {
|
|
|
1469
1490
|
callback(arg2);
|
|
1470
1491
|
return instance;
|
|
1471
1492
|
}
|
|
1472
|
-
static tap(
|
|
1473
|
-
|
|
1493
|
+
static tap(arg1, arg2) {
|
|
1494
|
+
const instance = this.get();
|
|
1495
|
+
return typeof arg1 == "function"
|
|
1496
|
+
? useCompute(instance, arg1, arg2)
|
|
1497
|
+
: useSubscribe(instance, arg1, arg2);
|
|
1474
1498
|
}
|
|
1475
1499
|
static use(a, b) {
|
|
1476
1500
|
return useNew(this, a, b);
|
|
1477
1501
|
}
|
|
1478
|
-
static meta(
|
|
1479
|
-
return
|
|
1502
|
+
static meta(arg1, arg2) {
|
|
1503
|
+
return typeof arg1 == "function"
|
|
1504
|
+
? useCompute(this, arg1, arg2)
|
|
1505
|
+
: useSubscribe(this, arg1, arg2);
|
|
1480
1506
|
}
|
|
1481
1507
|
}
|
|
1482
1508
|
|
|
@@ -1500,52 +1526,39 @@ const Oops = issues({
|
|
|
1500
1526
|
});
|
|
1501
1527
|
function Provider(props) {
|
|
1502
1528
|
const context = useNewContext(props.for, props.and);
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
? React__default["default"].createElement(RenderFunction, { context, render })
|
|
1507
|
-
: render);
|
|
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))));
|
|
1508
1532
|
}
|
|
1509
1533
|
function useNewContext(include, assign) {
|
|
1534
|
+
const init = new Set();
|
|
1510
1535
|
const ambient = useLookup();
|
|
1511
1536
|
const context = React__default["default"].useMemo(() => {
|
|
1512
1537
|
if (!include)
|
|
1513
1538
|
throw Oops.NoType();
|
|
1514
|
-
|
|
1515
|
-
if (include instanceof Model || typeof include == "function")
|
|
1516
|
-
next.add(include);
|
|
1517
|
-
else
|
|
1518
|
-
values(include).forEach(x => next.add(x));
|
|
1519
|
-
for (const instance of next.local)
|
|
1520
|
-
if (instance) {
|
|
1521
|
-
if (assign)
|
|
1522
|
-
assignWeak(instance, assign);
|
|
1523
|
-
for (const apply of getPending(instance))
|
|
1524
|
-
apply(next);
|
|
1525
|
-
}
|
|
1526
|
-
return next;
|
|
1539
|
+
return ambient.push();
|
|
1527
1540
|
}, []);
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1541
|
+
function register(key, T) {
|
|
1542
|
+
const instance = context.has(key, T, i => init.add(i));
|
|
1543
|
+
if (assign)
|
|
1544
|
+
assignWeak(instance, assign);
|
|
1545
|
+
}
|
|
1546
|
+
if (typeof include == "function" || include instanceof Model)
|
|
1547
|
+
register(0, include);
|
|
1548
|
+
else
|
|
1549
|
+
entries(include).forEach(e => register(...e));
|
|
1550
|
+
for (const instance of init) {
|
|
1551
|
+
control(instance).state.forEach(value => {
|
|
1552
|
+
if (Parent.get(value) === instance) {
|
|
1553
|
+
context.add(value);
|
|
1554
|
+
init.add(value);
|
|
1555
|
+
}
|
|
1556
|
+
});
|
|
1557
|
+
for (const apply of getPending(instance))
|
|
1558
|
+
apply(context);
|
|
1559
|
+
}
|
|
1560
|
+
React__default["default"].useLayoutEffect(() => () => context.pop(), []);
|
|
1532
1561
|
return context;
|
|
1533
|
-
}
|
|
1534
|
-
function RenderFunction(props) {
|
|
1535
|
-
const hook = use(refresh => {
|
|
1536
|
-
const targets = props.context.local;
|
|
1537
|
-
if (targets.length == 1)
|
|
1538
|
-
return Control.for(targets[0]).subscribe(() => refresh);
|
|
1539
|
-
return {};
|
|
1540
|
-
});
|
|
1541
|
-
if (hook.commit)
|
|
1542
|
-
React__default["default"].useLayoutEffect(hook.commit, []);
|
|
1543
|
-
return props.render(hook.proxy);
|
|
1544
|
-
}
|
|
1545
|
-
function assignWeak(into, from) {
|
|
1546
|
-
for (const K in from)
|
|
1547
|
-
if (K in into)
|
|
1548
|
-
into[K] = from[K];
|
|
1549
1562
|
}
|
|
1550
1563
|
|
|
1551
1564
|
class Global extends MVC {
|
|
@@ -1560,17 +1573,17 @@ const CONTROL = "$debug controller";
|
|
|
1560
1573
|
defineProperties(Model.prototype, {
|
|
1561
1574
|
[CONTROL]: {
|
|
1562
1575
|
get() {
|
|
1563
|
-
return
|
|
1576
|
+
return controller(this);
|
|
1564
1577
|
}
|
|
1565
1578
|
},
|
|
1566
1579
|
[LOCAL]: {
|
|
1567
1580
|
get() {
|
|
1568
|
-
return
|
|
1581
|
+
return subscriber(this);
|
|
1569
1582
|
}
|
|
1570
1583
|
},
|
|
1571
1584
|
[STATE]: {
|
|
1572
1585
|
get() {
|
|
1573
|
-
const { state } =
|
|
1586
|
+
const { state } = controller(this);
|
|
1574
1587
|
const output = {};
|
|
1575
1588
|
state.forEach((value, key) => output[key] = value);
|
|
1576
1589
|
return output;
|
|
@@ -1578,8 +1591,7 @@ defineProperties(Model.prototype, {
|
|
|
1578
1591
|
},
|
|
1579
1592
|
[UPDATE]: {
|
|
1580
1593
|
get() {
|
|
1581
|
-
|
|
1582
|
-
return source && source.latest;
|
|
1594
|
+
return (subscriber(this) || controller(this)).latest;
|
|
1583
1595
|
}
|
|
1584
1596
|
}
|
|
1585
1597
|
});
|