@expressive/mvc 0.4.3 → 0.4.4
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 +2 -1
- package/lib/index.esm.js +112 -101
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +112 -101
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ declare class Subscriber<T extends Stateful = any> {
|
|
|
35
35
|
release: Callback;
|
|
36
36
|
active: boolean;
|
|
37
37
|
dependant: Set<Listener>;
|
|
38
|
-
add: (key: any, value?: Callback) => void;
|
|
38
|
+
add: (key: any, value?: boolean | Callback) => void;
|
|
39
39
|
constructor(parent: Controller<T>, onUpdate: Controller.OnEvent);
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -220,6 +220,7 @@ declare namespace Instruction {
|
|
|
220
220
|
get?: Getter<T>;
|
|
221
221
|
set?: Setter<T> | false;
|
|
222
222
|
suspense?: boolean;
|
|
223
|
+
destroy?: () => void;
|
|
223
224
|
}
|
|
224
225
|
interface ExplicitDescriptor extends PropertyDescriptor {
|
|
225
226
|
explicit: true;
|
package/lib/index.esm.js
CHANGED
|
@@ -164,11 +164,10 @@ const Oops$a = issues({
|
|
|
164
164
|
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
165
165
|
});
|
|
166
166
|
const INFO = new WeakMap();
|
|
167
|
-
const USED = new WeakMap();
|
|
168
167
|
const KEYS = new WeakMap();
|
|
168
|
+
const ORDER = new WeakMap();
|
|
169
169
|
function from(source, arg1, arg2) {
|
|
170
170
|
return apply(function from(key) {
|
|
171
|
-
const parent = this;
|
|
172
171
|
const { subject, state } = this;
|
|
173
172
|
const required = arg2 === true || arg1 === true;
|
|
174
173
|
let getSource;
|
|
@@ -189,14 +188,13 @@ function from(source, arg1, arg2) {
|
|
|
189
188
|
else
|
|
190
189
|
throw Oops$a.BadSource(subject, key, source);
|
|
191
190
|
const setter = arg1;
|
|
192
|
-
const info = { key, parent
|
|
191
|
+
const info = { key, parent: this };
|
|
193
192
|
let sub;
|
|
194
|
-
let
|
|
195
|
-
if (!
|
|
196
|
-
|
|
193
|
+
let order = ORDER.get(this);
|
|
194
|
+
if (!order)
|
|
195
|
+
ORDER.set(this, order = []);
|
|
197
196
|
state.set(key, undefined);
|
|
198
|
-
|
|
199
|
-
function compute(initial) {
|
|
197
|
+
const compute = (initial) => {
|
|
200
198
|
try {
|
|
201
199
|
return setter.call(sub.proxy, sub.proxy);
|
|
202
200
|
}
|
|
@@ -204,8 +202,8 @@ function from(source, arg1, arg2) {
|
|
|
204
202
|
Oops$a.Failed(subject, key, initial).warn();
|
|
205
203
|
throw err;
|
|
206
204
|
}
|
|
207
|
-
}
|
|
208
|
-
|
|
205
|
+
};
|
|
206
|
+
const refreshValue = () => {
|
|
209
207
|
let value;
|
|
210
208
|
try {
|
|
211
209
|
value = compute(false);
|
|
@@ -215,26 +213,25 @@ function from(source, arg1, arg2) {
|
|
|
215
213
|
}
|
|
216
214
|
finally {
|
|
217
215
|
if (state.get(key) !== value) {
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
state.set(key, value);
|
|
217
|
+
this.update(key);
|
|
220
218
|
return value;
|
|
221
219
|
}
|
|
222
220
|
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (info.parent !== from)
|
|
229
|
-
update();
|
|
230
|
-
else {
|
|
231
|
-
const after = pending.findIndex(peer => (info.priority > INFO.get(peer).priority));
|
|
232
|
-
pending.splice(after + 1, 0, update);
|
|
221
|
+
};
|
|
222
|
+
const dependancyDidUpdate = (_key, source) => {
|
|
223
|
+
if (source !== this) {
|
|
224
|
+
refreshValue();
|
|
225
|
+
return;
|
|
233
226
|
}
|
|
234
|
-
|
|
235
|
-
|
|
227
|
+
let pending = KEYS.get(this);
|
|
228
|
+
if (!pending)
|
|
229
|
+
KEYS.set(this, pending = []);
|
|
230
|
+
pending.push(refreshValue);
|
|
231
|
+
};
|
|
232
|
+
const create = () => {
|
|
236
233
|
const control = getSource();
|
|
237
|
-
sub = control.subscribe(
|
|
234
|
+
sub = control.subscribe(dependancyDidUpdate);
|
|
238
235
|
try {
|
|
239
236
|
const value = compute(true);
|
|
240
237
|
state.set(key, value);
|
|
@@ -245,14 +242,10 @@ function from(source, arg1, arg2) {
|
|
|
245
242
|
}
|
|
246
243
|
finally {
|
|
247
244
|
sub.commit();
|
|
248
|
-
|
|
249
|
-
const peer = register.get(key);
|
|
250
|
-
if (peer && peer.priority >= info.priority)
|
|
251
|
-
info.priority = peer.priority + 1;
|
|
252
|
-
}
|
|
245
|
+
order.push(refreshValue);
|
|
253
246
|
}
|
|
254
|
-
}
|
|
255
|
-
INFO.set(
|
|
247
|
+
};
|
|
248
|
+
INFO.set(refreshValue, info);
|
|
256
249
|
return () => {
|
|
257
250
|
const value = sub ? state.get(key) : create();
|
|
258
251
|
if (value === undefined && required)
|
|
@@ -265,8 +258,11 @@ function flush(control) {
|
|
|
265
258
|
const pending = KEYS.get(control);
|
|
266
259
|
if (!pending)
|
|
267
260
|
return;
|
|
261
|
+
const list = ORDER.get(control);
|
|
268
262
|
while (pending.length) {
|
|
269
|
-
const compute = pending
|
|
263
|
+
const compute = pending
|
|
264
|
+
.sort((a, b) => list.indexOf(b) - list.indexOf(a))
|
|
265
|
+
.pop();
|
|
270
266
|
const { key } = INFO.get(compute);
|
|
271
267
|
if (!control.frame.has(key))
|
|
272
268
|
compute();
|
|
@@ -291,18 +287,16 @@ class Subscriber {
|
|
|
291
287
|
}
|
|
292
288
|
});
|
|
293
289
|
const release = parent.addListener(key => {
|
|
294
|
-
if (!this.active
|
|
290
|
+
if (!this.active)
|
|
295
291
|
return;
|
|
296
292
|
const handler = using.get(key);
|
|
297
293
|
let notify;
|
|
298
294
|
if (typeof handler == "function") {
|
|
299
295
|
const callback = handler();
|
|
300
|
-
if (
|
|
301
|
-
notify = callback;
|
|
302
|
-
else if (callback === true)
|
|
296
|
+
if (callback === true)
|
|
303
297
|
notify = this.onUpdate(key, parent);
|
|
304
298
|
}
|
|
305
|
-
else
|
|
299
|
+
else if (handler === true)
|
|
306
300
|
notify = this.onUpdate(key, parent);
|
|
307
301
|
const getWhy = () => {
|
|
308
302
|
const update = getUpdate(parent.subject);
|
|
@@ -324,7 +318,7 @@ class Subscriber {
|
|
|
324
318
|
release();
|
|
325
319
|
};
|
|
326
320
|
this.add = (key, value) => {
|
|
327
|
-
if (value)
|
|
321
|
+
if (value !== undefined)
|
|
328
322
|
using.set(key, value);
|
|
329
323
|
else if (!using.has(key))
|
|
330
324
|
using.set(key, true);
|
|
@@ -398,17 +392,15 @@ class Controller {
|
|
|
398
392
|
else if (!frame.size)
|
|
399
393
|
setTimeout(() => {
|
|
400
394
|
flush(this);
|
|
401
|
-
|
|
402
|
-
const keys = Array.from(frame);
|
|
403
|
-
frame.clear();
|
|
404
|
-
waiting.clear();
|
|
405
|
-
UPDATE.set(subject, keys);
|
|
395
|
+
UPDATE.set(subject, Array.from(frame));
|
|
406
396
|
setTimeout(() => {
|
|
407
397
|
UPDATE.delete(subject);
|
|
408
398
|
}, 0);
|
|
409
|
-
|
|
399
|
+
frame.clear();
|
|
400
|
+
for (const notify of waiting)
|
|
410
401
|
try {
|
|
411
|
-
|
|
402
|
+
waiting.delete(notify);
|
|
403
|
+
notify();
|
|
412
404
|
}
|
|
413
405
|
catch (err) {
|
|
414
406
|
console.error(err);
|
|
@@ -659,6 +651,14 @@ function apply(fn, label) {
|
|
|
659
651
|
const desc = output;
|
|
660
652
|
if ("value" in desc)
|
|
661
653
|
state.set(key, desc.value);
|
|
654
|
+
if ("destroy" in output) {
|
|
655
|
+
const { destroy } = output;
|
|
656
|
+
if (destroy)
|
|
657
|
+
this.addListener((key) => {
|
|
658
|
+
if (key == null)
|
|
659
|
+
destroy();
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
662
|
const { get: onGet, set: onSet, enumerable, suspense } = desc;
|
|
663
663
|
const set = onSet !== false
|
|
664
664
|
? this.ref(key, onSet)
|
|
@@ -940,39 +940,31 @@ const ANY$1 = Symbol("any");
|
|
|
940
940
|
function managedMap(control, property, initial) {
|
|
941
941
|
const managed = new ManagedMap(initial, emit);
|
|
942
942
|
const context = new WeakMap();
|
|
943
|
-
const
|
|
943
|
+
const observers = new Set();
|
|
944
|
+
const frozen = new Set();
|
|
944
945
|
function reset() {
|
|
945
|
-
|
|
946
|
+
frozen.clear();
|
|
946
947
|
}
|
|
947
948
|
function emit(key) {
|
|
948
|
-
|
|
949
|
+
observers.forEach(notify => notify(key));
|
|
949
950
|
control.update(property);
|
|
950
951
|
control.waiting.add(reset);
|
|
951
952
|
}
|
|
952
|
-
function
|
|
953
|
-
control.state.set(property, next);
|
|
954
|
-
managed.source = next;
|
|
955
|
-
emit(ANY$1);
|
|
956
|
-
}
|
|
957
|
-
function getValue(local) {
|
|
958
|
-
if (!local)
|
|
959
|
-
return managed;
|
|
960
|
-
if (context.has(local))
|
|
961
|
-
return context.get(local);
|
|
962
|
-
const refresh = local.onUpdate(property, control);
|
|
953
|
+
function init(local) {
|
|
963
954
|
const proxy = create(managed);
|
|
964
955
|
const using = new Set();
|
|
965
|
-
|
|
966
|
-
if (
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
956
|
+
observers.add(key => {
|
|
957
|
+
if (frozen.has(local))
|
|
958
|
+
return;
|
|
959
|
+
if (using.has(key) || using.has(ANY$1) || key === ANY$1 && using.size) {
|
|
960
|
+
const refresh = local.onUpdate(property, control);
|
|
961
|
+
if (refresh) {
|
|
962
|
+
frozen.add(local);
|
|
963
|
+
refresh();
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
local.add(property, false);
|
|
976
968
|
context.set(local, proxy);
|
|
977
969
|
proxy.watch = (key) => {
|
|
978
970
|
if (!local.active)
|
|
@@ -982,8 +974,21 @@ function managedMap(control, property, initial) {
|
|
|
982
974
|
}
|
|
983
975
|
return {
|
|
984
976
|
value: initial,
|
|
985
|
-
|
|
986
|
-
|
|
977
|
+
get(local) {
|
|
978
|
+
if (!local)
|
|
979
|
+
return managed;
|
|
980
|
+
if (context.has(local))
|
|
981
|
+
return context.get(local);
|
|
982
|
+
return init(local);
|
|
983
|
+
},
|
|
984
|
+
set(next) {
|
|
985
|
+
managed.source = next;
|
|
986
|
+
control.state.set(property, next);
|
|
987
|
+
emit(ANY$1);
|
|
988
|
+
},
|
|
989
|
+
destroy() {
|
|
990
|
+
observers.clear();
|
|
991
|
+
}
|
|
987
992
|
};
|
|
988
993
|
}
|
|
989
994
|
class ManagedMap {
|
|
@@ -1045,39 +1050,31 @@ const ANY = Symbol("any");
|
|
|
1045
1050
|
function managedSet(control, property, initial) {
|
|
1046
1051
|
const managed = new ManagedSet(initial, emit);
|
|
1047
1052
|
const context = new WeakMap();
|
|
1048
|
-
const
|
|
1053
|
+
const observers = new Set();
|
|
1054
|
+
const frozen = new Set();
|
|
1049
1055
|
function reset() {
|
|
1050
|
-
|
|
1056
|
+
frozen.clear();
|
|
1051
1057
|
}
|
|
1052
1058
|
function emit(key) {
|
|
1053
|
-
|
|
1059
|
+
observers.forEach(notify => notify(key));
|
|
1054
1060
|
control.update(property);
|
|
1055
1061
|
control.waiting.add(reset);
|
|
1056
1062
|
}
|
|
1057
|
-
function
|
|
1058
|
-
managed.source = next;
|
|
1059
|
-
control.state.set(property, next);
|
|
1060
|
-
emit(ANY);
|
|
1061
|
-
}
|
|
1062
|
-
function getValue(local) {
|
|
1063
|
-
if (!local)
|
|
1064
|
-
return managed;
|
|
1065
|
-
if (context.has(local))
|
|
1066
|
-
return context.get(local);
|
|
1067
|
-
const refresh = local.onUpdate(property, control);
|
|
1063
|
+
function init(local) {
|
|
1068
1064
|
const proxy = create(managed);
|
|
1069
1065
|
const using = new Set();
|
|
1070
|
-
|
|
1071
|
-
if (
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1066
|
+
observers.add(key => {
|
|
1067
|
+
if (frozen.has(local))
|
|
1068
|
+
return;
|
|
1069
|
+
if (using.has(key) || using.has(ANY) || key === ANY && using.size) {
|
|
1070
|
+
const refresh = local.onUpdate(property, control);
|
|
1071
|
+
if (refresh) {
|
|
1072
|
+
frozen.add(local);
|
|
1073
|
+
refresh();
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
local.add(property, false);
|
|
1081
1078
|
context.set(local, proxy);
|
|
1082
1079
|
proxy.watch = (key) => {
|
|
1083
1080
|
if (!local.active)
|
|
@@ -1087,8 +1084,21 @@ function managedSet(control, property, initial) {
|
|
|
1087
1084
|
}
|
|
1088
1085
|
return {
|
|
1089
1086
|
value: initial,
|
|
1090
|
-
|
|
1091
|
-
|
|
1087
|
+
get(local) {
|
|
1088
|
+
if (!local)
|
|
1089
|
+
return managed;
|
|
1090
|
+
if (context.has(local))
|
|
1091
|
+
return context.get(local);
|
|
1092
|
+
return init(local);
|
|
1093
|
+
},
|
|
1094
|
+
set(next) {
|
|
1095
|
+
managed.source = next;
|
|
1096
|
+
control.state.set(property, next);
|
|
1097
|
+
emit(ANY);
|
|
1098
|
+
},
|
|
1099
|
+
destroy() {
|
|
1100
|
+
observers.clear();
|
|
1101
|
+
}
|
|
1092
1102
|
};
|
|
1093
1103
|
}
|
|
1094
1104
|
class ManagedSet {
|
|
@@ -1098,8 +1108,9 @@ class ManagedSet {
|
|
|
1098
1108
|
}
|
|
1099
1109
|
watch(_key) { }
|
|
1100
1110
|
add(key) {
|
|
1111
|
+
this.source.add(key);
|
|
1101
1112
|
this.emit(key);
|
|
1102
|
-
return this
|
|
1113
|
+
return this;
|
|
1103
1114
|
}
|
|
1104
1115
|
;
|
|
1105
1116
|
delete(key) {
|