@expressive/mvc 0.8.2 → 0.9.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 +44 -36
- package/lib/index.esm.js +200 -177
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +201 -178
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -17,44 +17,13 @@ function issues(register) {
|
|
|
17
17
|
return Library;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
22
|
-
});
|
|
23
|
-
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
24
|
-
function createEffect(callback) {
|
|
25
|
-
let unSet;
|
|
26
|
-
return function (value) {
|
|
27
|
-
if (typeof unSet == "function")
|
|
28
|
-
unSet();
|
|
29
|
-
unSet = callback.call(this, value);
|
|
30
|
-
if (unSet instanceof Promise)
|
|
31
|
-
unSet = undefined;
|
|
32
|
-
if (unSet && typeof unSet !== "function")
|
|
33
|
-
throw Oops$d.BadCallback();
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function createValueEffect(callback) {
|
|
37
|
-
let unSet;
|
|
38
|
-
return function (value) {
|
|
39
|
-
if (typeof unSet == "function")
|
|
40
|
-
unSet(value);
|
|
41
|
-
const out = callback.call(this, value, this);
|
|
42
|
-
if (typeof out == "boolean")
|
|
43
|
-
return out;
|
|
44
|
-
if (!out || out instanceof Promise)
|
|
45
|
-
return;
|
|
46
|
-
if (typeof out == "function")
|
|
47
|
-
unSet = out;
|
|
48
|
-
else
|
|
49
|
-
throw Oops$d.BadCallback();
|
|
50
|
-
};
|
|
51
|
-
}
|
|
20
|
+
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
52
21
|
|
|
53
|
-
const Oops$
|
|
22
|
+
const Oops$d = issues({
|
|
54
23
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
55
24
|
});
|
|
56
25
|
function suspend(source, key) {
|
|
57
|
-
const error = Oops$
|
|
26
|
+
const error = Oops$d.NotReady(source.subject, key);
|
|
58
27
|
const promise = new Promise(resolve => {
|
|
59
28
|
const release = source.addListener(forKey => {
|
|
60
29
|
if (forKey == key)
|
|
@@ -94,7 +63,7 @@ function mayRetry(fn) {
|
|
|
94
63
|
return compute();
|
|
95
64
|
}
|
|
96
65
|
|
|
97
|
-
const Oops$
|
|
66
|
+
const Oops$c = issues({
|
|
98
67
|
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
99
68
|
});
|
|
100
69
|
const INFO = new WeakMap();
|
|
@@ -104,14 +73,17 @@ function computeMode(self, source, setter, key, required) {
|
|
|
104
73
|
const { subject, state } = self;
|
|
105
74
|
let sub;
|
|
106
75
|
let order = ORDER.get(self);
|
|
76
|
+
let pending = KEYS.get(self);
|
|
107
77
|
if (!order)
|
|
108
|
-
ORDER.set(self, order =
|
|
78
|
+
ORDER.set(self, order = new Map());
|
|
79
|
+
if (!pending)
|
|
80
|
+
KEYS.set(self, pending = new Set());
|
|
109
81
|
const compute = (initial) => {
|
|
110
82
|
try {
|
|
111
83
|
return setter.call(sub.proxy, sub.proxy);
|
|
112
84
|
}
|
|
113
85
|
catch (err) {
|
|
114
|
-
Oops$
|
|
86
|
+
Oops$c.Failed(subject, key, initial).warn();
|
|
115
87
|
throw err;
|
|
116
88
|
}
|
|
117
89
|
};
|
|
@@ -131,18 +103,13 @@ function computeMode(self, source, setter, key, required) {
|
|
|
131
103
|
}
|
|
132
104
|
}
|
|
133
105
|
};
|
|
134
|
-
const update = (_key, source) => {
|
|
135
|
-
if (source !== self) {
|
|
136
|
-
refresh();
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
let pending = KEYS.get(self);
|
|
140
|
-
if (!pending)
|
|
141
|
-
KEYS.set(self, pending = []);
|
|
142
|
-
pending.push(refresh);
|
|
143
|
-
};
|
|
144
106
|
const create = () => {
|
|
145
|
-
sub = source.subscribe(
|
|
107
|
+
sub = source.subscribe((_, source) => {
|
|
108
|
+
if (source !== self)
|
|
109
|
+
refresh();
|
|
110
|
+
else
|
|
111
|
+
pending.add(refresh);
|
|
112
|
+
});
|
|
146
113
|
try {
|
|
147
114
|
const value = compute(true);
|
|
148
115
|
state.set(key, value);
|
|
@@ -153,11 +120,15 @@ function computeMode(self, source, setter, key, required) {
|
|
|
153
120
|
}
|
|
154
121
|
finally {
|
|
155
122
|
sub.commit();
|
|
156
|
-
order.
|
|
123
|
+
order.set(refresh, order.size);
|
|
157
124
|
}
|
|
158
125
|
};
|
|
159
126
|
INFO.set(refresh, key);
|
|
160
127
|
return () => {
|
|
128
|
+
if (pending.has(refresh)) {
|
|
129
|
+
pending.delete(refresh);
|
|
130
|
+
refresh();
|
|
131
|
+
}
|
|
161
132
|
const value = sub ? state.get(key) : create();
|
|
162
133
|
if (value === undefined && required)
|
|
163
134
|
throw suspend(self, key);
|
|
@@ -166,18 +137,20 @@ function computeMode(self, source, setter, key, required) {
|
|
|
166
137
|
}
|
|
167
138
|
function flush(control) {
|
|
168
139
|
const pending = KEYS.get(control);
|
|
169
|
-
if (!pending)
|
|
140
|
+
if (!pending || !pending.size)
|
|
170
141
|
return;
|
|
171
|
-
const
|
|
172
|
-
while (pending.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
.
|
|
142
|
+
const priority = ORDER.get(control);
|
|
143
|
+
while (pending.size) {
|
|
144
|
+
let compute;
|
|
145
|
+
for (const item of pending)
|
|
146
|
+
if (!compute || priority.get(item) < priority.get(compute))
|
|
147
|
+
compute = item;
|
|
148
|
+
pending.delete(compute);
|
|
176
149
|
const key = INFO.get(compute);
|
|
177
150
|
if (!control.frame.has(key))
|
|
178
151
|
compute();
|
|
179
152
|
}
|
|
180
|
-
|
|
153
|
+
pending.clear();
|
|
181
154
|
}
|
|
182
155
|
|
|
183
156
|
const REGISTER$1 = new WeakMap();
|
|
@@ -212,8 +185,8 @@ class Subscriber {
|
|
|
212
185
|
notify = this.onUpdate(key, parent);
|
|
213
186
|
if (!notify)
|
|
214
187
|
return;
|
|
215
|
-
parent.waiting.add(
|
|
216
|
-
this.latest =
|
|
188
|
+
parent.waiting.add(update => {
|
|
189
|
+
this.latest = update.filter(k => watch.has(k));
|
|
217
190
|
});
|
|
218
191
|
parent.waiting.add(notify);
|
|
219
192
|
};
|
|
@@ -320,13 +293,13 @@ class Control {
|
|
|
320
293
|
else if (!frame.size)
|
|
321
294
|
setTimeout(() => {
|
|
322
295
|
flush(this);
|
|
323
|
-
this.latest = Array.from(frame);
|
|
296
|
+
const keys = this.latest = Array.from(frame);
|
|
324
297
|
setTimeout(() => this.latest = undefined, 0);
|
|
325
298
|
frame.clear();
|
|
326
299
|
for (const notify of waiting)
|
|
327
300
|
try {
|
|
328
301
|
waiting.delete(notify);
|
|
329
|
-
notify();
|
|
302
|
+
notify(keys);
|
|
330
303
|
}
|
|
331
304
|
catch (err) {
|
|
332
305
|
console.error(err);
|
|
@@ -354,18 +327,21 @@ class Control {
|
|
|
354
327
|
if (!control.state) {
|
|
355
328
|
const { waiting } = control;
|
|
356
329
|
if (cb) {
|
|
357
|
-
let
|
|
330
|
+
let callback;
|
|
358
331
|
waiting.add(() => {
|
|
359
|
-
|
|
332
|
+
callback = cb(control);
|
|
360
333
|
});
|
|
361
|
-
return () =>
|
|
334
|
+
return () => {
|
|
335
|
+
if (callback)
|
|
336
|
+
callback();
|
|
337
|
+
};
|
|
362
338
|
}
|
|
363
339
|
control.state = new Map();
|
|
364
340
|
for (const key in subject)
|
|
365
341
|
control.watch(key);
|
|
366
342
|
control.waiting = new Set();
|
|
367
343
|
for (const cb of waiting)
|
|
368
|
-
cb();
|
|
344
|
+
cb([]);
|
|
369
345
|
}
|
|
370
346
|
return cb ? cb(control) : control;
|
|
371
347
|
}
|
|
@@ -481,15 +457,15 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
481
457
|
});
|
|
482
458
|
}
|
|
483
459
|
|
|
484
|
-
const Oops$
|
|
460
|
+
const Oops$b = issues({
|
|
485
461
|
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
486
462
|
});
|
|
487
|
-
function
|
|
488
|
-
return add(function
|
|
463
|
+
function run(task) {
|
|
464
|
+
return add(function run(key) {
|
|
489
465
|
let pending = false;
|
|
490
466
|
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
491
467
|
if (pending)
|
|
492
|
-
return Promise.reject(Oops$
|
|
468
|
+
return Promise.reject(Oops$b.DuplicatePending(key));
|
|
493
469
|
pending = true;
|
|
494
470
|
this.update(key);
|
|
495
471
|
try {
|
|
@@ -511,7 +487,7 @@ function act(task) {
|
|
|
511
487
|
});
|
|
512
488
|
}
|
|
513
489
|
|
|
514
|
-
const Oops$
|
|
490
|
+
const Oops$a = issues({
|
|
515
491
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
516
492
|
});
|
|
517
493
|
function factoryMode(self, output, key, required) {
|
|
@@ -535,7 +511,7 @@ function factoryMode(self, output, key, required) {
|
|
|
535
511
|
const suspend = () => {
|
|
536
512
|
if (required === false)
|
|
537
513
|
return undefined;
|
|
538
|
-
const issue = Oops$
|
|
514
|
+
const issue = Oops$a.NotReady(subject, key);
|
|
539
515
|
assign(pending, {
|
|
540
516
|
message: issue.message,
|
|
541
517
|
stack: issue.stack
|
|
@@ -552,7 +528,7 @@ function factoryMode(self, output, key, required) {
|
|
|
552
528
|
};
|
|
553
529
|
}
|
|
554
530
|
|
|
555
|
-
const Oops$
|
|
531
|
+
const Oops$9 = issues({
|
|
556
532
|
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
557
533
|
ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
|
|
558
534
|
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
@@ -565,7 +541,7 @@ function get(arg0, arg1, arg2) {
|
|
|
565
541
|
let getter;
|
|
566
542
|
// Easy mistake, using a peer, will always be unresolved.
|
|
567
543
|
if (typeof arg0 == "symbol")
|
|
568
|
-
throw Oops$
|
|
544
|
+
throw Oops$9.PeerNotAllowed(subject, key);
|
|
569
545
|
// if(typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
|
|
570
546
|
// throw Oops.BadSource(subject, key, arg0);
|
|
571
547
|
this.state.set(key, undefined);
|
|
@@ -599,7 +575,7 @@ function get(arg0, arg1, arg2) {
|
|
|
599
575
|
init();
|
|
600
576
|
}
|
|
601
577
|
catch (err) {
|
|
602
|
-
Oops$
|
|
578
|
+
Oops$9.ComputeFailed(subject, key).warn();
|
|
603
579
|
throw err;
|
|
604
580
|
}
|
|
605
581
|
return () => {
|
|
@@ -610,6 +586,67 @@ function get(arg0, arg1, arg2) {
|
|
|
610
586
|
});
|
|
611
587
|
}
|
|
612
588
|
|
|
589
|
+
const Oops$8 = issues({
|
|
590
|
+
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
591
|
+
});
|
|
592
|
+
function createEffect(model, callback, keys) {
|
|
593
|
+
return Control.for(model, control => {
|
|
594
|
+
let unSet;
|
|
595
|
+
let busy = false;
|
|
596
|
+
function effect(value) {
|
|
597
|
+
if (typeof unSet == "function")
|
|
598
|
+
unSet();
|
|
599
|
+
unSet = callback.call(this, value);
|
|
600
|
+
if (unSet instanceof Promise)
|
|
601
|
+
unSet = undefined;
|
|
602
|
+
if (unSet && typeof unSet !== "function")
|
|
603
|
+
throw Oops$8.BadCallback();
|
|
604
|
+
}
|
|
605
|
+
function invoke() {
|
|
606
|
+
if (busy)
|
|
607
|
+
return;
|
|
608
|
+
const output = mayRetry(() => {
|
|
609
|
+
effect.call(model, model);
|
|
610
|
+
});
|
|
611
|
+
if (output instanceof Promise) {
|
|
612
|
+
output.finally(() => busy = false);
|
|
613
|
+
busy = true;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (Array.isArray(keys)) {
|
|
617
|
+
invoke();
|
|
618
|
+
return control.addListener(key => {
|
|
619
|
+
if (key === null) {
|
|
620
|
+
if (!keys.length)
|
|
621
|
+
invoke();
|
|
622
|
+
}
|
|
623
|
+
else if (keys.includes(key))
|
|
624
|
+
return invoke;
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
const sub = control.subscribe(() => invoke);
|
|
628
|
+
model = sub.proxy;
|
|
629
|
+
invoke();
|
|
630
|
+
return sub.commit();
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
function createValueEffect(callback) {
|
|
634
|
+
let unSet;
|
|
635
|
+
return function (value) {
|
|
636
|
+
if (typeof unSet == "function")
|
|
637
|
+
unSet(value);
|
|
638
|
+
const out = callback.call(this, value, this);
|
|
639
|
+
if (typeof out == "boolean")
|
|
640
|
+
return out;
|
|
641
|
+
if (!out || out instanceof Promise)
|
|
642
|
+
return;
|
|
643
|
+
if (typeof out == "function")
|
|
644
|
+
unSet = out;
|
|
645
|
+
else
|
|
646
|
+
throw Oops$8.BadCallback();
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
|
|
613
650
|
function ref(arg, mapper) {
|
|
614
651
|
return add(function ref(key) {
|
|
615
652
|
let value = {};
|
|
@@ -903,8 +940,10 @@ function has(Type, required) {
|
|
|
903
940
|
}
|
|
904
941
|
|
|
905
942
|
const Oops$5 = issues({
|
|
906
|
-
Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
|
|
907
|
-
|
|
943
|
+
Timeout: (keys, timeout) => `No update seen for [${keys}] within ${timeout}.`,
|
|
944
|
+
KeysExpected: (key) => `Key "${key}" was expected in current update.`,
|
|
945
|
+
StrictUpdate: () => `Expected update but none in progress.`,
|
|
946
|
+
StrictNoUpdate: () => `Update is not expected but one is in progress!`,
|
|
908
947
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
909
948
|
});
|
|
910
949
|
class Model {
|
|
@@ -912,91 +951,84 @@ class Model {
|
|
|
912
951
|
new Control(this);
|
|
913
952
|
defineProperty(this, "is", { value: this });
|
|
914
953
|
}
|
|
915
|
-
on(
|
|
916
|
-
if (typeof
|
|
917
|
-
return
|
|
918
|
-
const single = typeof
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
954
|
+
on(arg1, arg2, arg3) {
|
|
955
|
+
if (typeof arg1 == "function")
|
|
956
|
+
return createEffect(this.is, arg1, arg2);
|
|
957
|
+
const single = typeof arg1 == "string";
|
|
958
|
+
const keys = typeof arg1 == "string" ? [arg1] :
|
|
959
|
+
typeof arg1 == "object" ? arg1 :
|
|
960
|
+
undefined;
|
|
961
|
+
if (typeof arg2 == "function" && keys)
|
|
962
|
+
return Control.for(this, control => {
|
|
963
|
+
for (const key of keys)
|
|
964
|
+
try {
|
|
965
|
+
void this[key];
|
|
966
|
+
}
|
|
967
|
+
catch (e) { }
|
|
968
|
+
const invoke = single
|
|
969
|
+
? () => arg2.call(this, control.state.get(arg1), arg1)
|
|
970
|
+
: (frame) => arg2.call(this, frame);
|
|
971
|
+
const removeListener = control.addListener(key => {
|
|
972
|
+
if (!key && !keys.length)
|
|
973
|
+
invoke([]);
|
|
974
|
+
if (keys.includes(key)) {
|
|
975
|
+
if (arg3)
|
|
934
976
|
removeListener();
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
});
|
|
977
|
+
return invoke;
|
|
978
|
+
}
|
|
938
979
|
});
|
|
939
|
-
|
|
940
|
-
setTimeout(() => {
|
|
941
|
-
removeListener();
|
|
942
|
-
reject(Oops$5.Timeout(select, `${argument}ms`));
|
|
943
|
-
}, argument);
|
|
980
|
+
return removeListener;
|
|
944
981
|
});
|
|
945
|
-
return
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
982
|
+
return new Promise((resolve, reject) => {
|
|
983
|
+
const timeout = (message) => {
|
|
984
|
+
const k = keys ? keys.join(", ") : "any";
|
|
985
|
+
removeListener();
|
|
986
|
+
reject(Oops$5.Timeout(k, message));
|
|
987
|
+
};
|
|
988
|
+
const removeListener = Control.for(this, control => {
|
|
989
|
+
const pending = control.frame;
|
|
990
|
+
if (keys === null) {
|
|
991
|
+
if (pending.size)
|
|
992
|
+
reject(Oops$5.StrictNoUpdate());
|
|
993
|
+
else
|
|
994
|
+
resolve(null);
|
|
995
|
+
return;
|
|
951
996
|
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
997
|
+
if (keys) {
|
|
998
|
+
if (keys.length) {
|
|
999
|
+
if (arg2 === 0 && single && !pending.has(keys[0])) {
|
|
1000
|
+
reject(Oops$5.KeysExpected(keys[0]));
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
else
|
|
1004
|
+
for (const key of keys)
|
|
1005
|
+
try {
|
|
1006
|
+
void this[key];
|
|
1007
|
+
}
|
|
1008
|
+
catch (e) { }
|
|
1009
|
+
}
|
|
960
1010
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
if (keys.includes(key))
|
|
964
|
-
return onEvent;
|
|
965
|
-
});
|
|
966
|
-
return removeListener;
|
|
967
|
-
});
|
|
968
|
-
}
|
|
969
|
-
effect(callback, select) {
|
|
970
|
-
const effect = createEffect(callback);
|
|
971
|
-
return Control.for(this, control => {
|
|
972
|
-
let busy = false;
|
|
973
|
-
let inject = this.is;
|
|
974
|
-
const invoke = () => {
|
|
975
|
-
if (busy)
|
|
1011
|
+
else if (!pending.size && arg1 === true || arg2 === 0) {
|
|
1012
|
+
reject(Oops$5.StrictUpdate());
|
|
976
1013
|
return;
|
|
977
|
-
const output = mayRetry(() => {
|
|
978
|
-
effect.call(inject, inject);
|
|
979
|
-
});
|
|
980
|
-
if (output instanceof Promise) {
|
|
981
|
-
output.finally(() => busy = false);
|
|
982
|
-
busy = true;
|
|
983
|
-
}
|
|
984
|
-
};
|
|
985
|
-
if (!select) {
|
|
986
|
-
const sub = control.subscribe(() => invoke);
|
|
987
|
-
inject = sub.proxy;
|
|
988
|
-
invoke();
|
|
989
|
-
return sub.commit();
|
|
990
|
-
}
|
|
991
|
-
invoke();
|
|
992
|
-
return control.addListener(key => {
|
|
993
|
-
if (key === null) {
|
|
994
|
-
if (!select.length)
|
|
995
|
-
invoke();
|
|
996
1014
|
}
|
|
997
|
-
else
|
|
998
|
-
|
|
1015
|
+
else
|
|
1016
|
+
control.waiting.add(resolve);
|
|
1017
|
+
return control.addListener(key => {
|
|
1018
|
+
if (!key) {
|
|
1019
|
+
if (keys && !keys.length)
|
|
1020
|
+
resolve([]);
|
|
1021
|
+
else
|
|
1022
|
+
timeout(`lifetime of ${this}`);
|
|
1023
|
+
}
|
|
1024
|
+
else if (!keys || keys.includes(key)) {
|
|
1025
|
+
removeListener();
|
|
1026
|
+
return keys => resolve(single ? control.state.get(key) : keys);
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
999
1029
|
});
|
|
1030
|
+
if (arg2 && typeof arg2 == "number")
|
|
1031
|
+
setTimeout(() => timeout(`${arg2}ms`), arg2);
|
|
1000
1032
|
});
|
|
1001
1033
|
}
|
|
1002
1034
|
export(subset) {
|
|
@@ -1009,13 +1041,10 @@ class Model {
|
|
|
1009
1041
|
}
|
|
1010
1042
|
update(arg1, arg2) {
|
|
1011
1043
|
const control = Control.for(this);
|
|
1012
|
-
const { frame, state, waiting } = control;
|
|
1013
|
-
if (arg1 === true && !frame.size)
|
|
1014
|
-
return Promise.reject(Oops$5.StrictUpdate());
|
|
1015
1044
|
if (typeof arg1 == "object") {
|
|
1016
1045
|
for (const key in arg1)
|
|
1017
|
-
if (arg2 === true || (arg2 ? arg2.includes(key) : state.has(key))) {
|
|
1018
|
-
state.set(key, arg1[key]);
|
|
1046
|
+
if (arg2 === true || (arg2 ? arg2.includes(key) : control.state.has(key))) {
|
|
1047
|
+
control.state.set(key, arg1[key]);
|
|
1019
1048
|
control.update(key);
|
|
1020
1049
|
}
|
|
1021
1050
|
}
|
|
@@ -1029,25 +1058,19 @@ class Model {
|
|
|
1029
1058
|
else if (arg2)
|
|
1030
1059
|
method.call(this);
|
|
1031
1060
|
}
|
|
1032
|
-
arg1 = undefined;
|
|
1033
1061
|
}
|
|
1034
1062
|
return {
|
|
1035
1063
|
then: (callback) => {
|
|
1036
1064
|
if (!callback)
|
|
1037
1065
|
throw Oops$5.NoChaining();
|
|
1038
|
-
|
|
1039
|
-
waiting.add(() => {
|
|
1040
|
-
callback(control.latest);
|
|
1041
|
-
});
|
|
1042
|
-
else
|
|
1043
|
-
callback(false);
|
|
1066
|
+
control.waiting.add(callback);
|
|
1044
1067
|
}
|
|
1045
1068
|
};
|
|
1046
1069
|
}
|
|
1047
1070
|
/**
|
|
1048
|
-
*
|
|
1071
|
+
* Clean up side effects and mark this instance for garbage-collection.
|
|
1049
1072
|
*/
|
|
1050
|
-
|
|
1073
|
+
destroy() {
|
|
1051
1074
|
Control.for(this).clear();
|
|
1052
1075
|
}
|
|
1053
1076
|
/**
|
|
@@ -1124,7 +1147,7 @@ class Lookup {
|
|
|
1124
1147
|
items.add(entry.value);
|
|
1125
1148
|
}
|
|
1126
1149
|
for (const model of items)
|
|
1127
|
-
model.
|
|
1150
|
+
model.destroy();
|
|
1128
1151
|
}
|
|
1129
1152
|
}
|
|
1130
1153
|
const LookupContext = React.createContext(new Lookup());
|
|
@@ -1224,7 +1247,7 @@ function useModel(source, arg, arg2) {
|
|
|
1224
1247
|
instance.on(arg, () => update(x => x + 1));
|
|
1225
1248
|
return () => {
|
|
1226
1249
|
if (Model.isTypeof(source))
|
|
1227
|
-
instance.
|
|
1250
|
+
instance.destroy();
|
|
1228
1251
|
};
|
|
1229
1252
|
}, []);
|
|
1230
1253
|
return instance;
|
|
@@ -1237,15 +1260,15 @@ function useModel(source, arg, arg2) {
|
|
|
1237
1260
|
return () => {
|
|
1238
1261
|
local.release();
|
|
1239
1262
|
if (Model.isTypeof(source))
|
|
1240
|
-
instance.
|
|
1263
|
+
instance.destroy();
|
|
1241
1264
|
};
|
|
1242
1265
|
}, []);
|
|
1243
1266
|
return local.proxy;
|
|
1244
1267
|
}
|
|
1245
1268
|
|
|
1246
|
-
function
|
|
1269
|
+
function useValue(source, compute, suspend) {
|
|
1247
1270
|
const local = use(refresh => {
|
|
1248
|
-
const sub = Control.for(
|
|
1271
|
+
const sub = Control.for(source).subscribe(() => update);
|
|
1249
1272
|
const spy = sub.proxy;
|
|
1250
1273
|
let value = compute.call(spy, spy);
|
|
1251
1274
|
let update;
|
|
@@ -1295,7 +1318,7 @@ function useTap(source, arg1, arg2) {
|
|
|
1295
1318
|
return source;
|
|
1296
1319
|
}, [])();
|
|
1297
1320
|
if (typeof arg1 == "function")
|
|
1298
|
-
return
|
|
1321
|
+
return useValue(instance, arg1, arg2);
|
|
1299
1322
|
const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
|
|
1300
1323
|
React.useLayoutEffect(local.commit, []);
|
|
1301
1324
|
if (arg1 === undefined)
|
|
@@ -1325,7 +1348,7 @@ const LOCAL = "$debug local";
|
|
|
1325
1348
|
const STATE = "$debug state";
|
|
1326
1349
|
const UPDATE = "$debug update";
|
|
1327
1350
|
const CONTROL = "$debug controller";
|
|
1328
|
-
|
|
1351
|
+
defineProperties(Model.prototype, {
|
|
1329
1352
|
[CONTROL]: {
|
|
1330
1353
|
get() {
|
|
1331
1354
|
return Control.get(this);
|
|
@@ -1444,11 +1467,11 @@ class Global extends MVC {
|
|
|
1444
1467
|
super();
|
|
1445
1468
|
Active.set(this.constructor, this);
|
|
1446
1469
|
}
|
|
1447
|
-
|
|
1470
|
+
destroy(force) {
|
|
1448
1471
|
const type = this.constructor;
|
|
1449
1472
|
if (type.keepAlive && !force)
|
|
1450
1473
|
return false;
|
|
1451
|
-
|
|
1474
|
+
Control.for(this).clear();
|
|
1452
1475
|
Active.delete(type);
|
|
1453
1476
|
return true;
|
|
1454
1477
|
}
|
|
@@ -1482,10 +1505,10 @@ class Global extends MVC {
|
|
|
1482
1505
|
static reset() {
|
|
1483
1506
|
const current = Active.get(this);
|
|
1484
1507
|
if (current)
|
|
1485
|
-
current.
|
|
1508
|
+
current.destroy(true);
|
|
1486
1509
|
}
|
|
1487
1510
|
}
|
|
1488
1511
|
Global.keepAlive = true;
|
|
1489
1512
|
|
|
1490
|
-
export { Consumer, Debug, Global, MVC, MVC as Model, Provider,
|
|
1513
|
+
export { Consumer, Debug, Global, MVC, MVC as Model, Provider, add, MVC as default, get, has, ref, run, set, tap, use$1 as use, useContext, useModel, useTap, useValue };
|
|
1491
1514
|
//# sourceMappingURL=index.esm.js.map
|