@expressive/mvc 0.4.1 → 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 +227 -196
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +227 -196
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -172,11 +172,10 @@ const Oops$a = issues({
|
|
|
172
172
|
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
173
173
|
});
|
|
174
174
|
const INFO = new WeakMap();
|
|
175
|
-
const USED = new WeakMap();
|
|
176
175
|
const KEYS = new WeakMap();
|
|
176
|
+
const ORDER = new WeakMap();
|
|
177
177
|
function from(source, arg1, arg2) {
|
|
178
178
|
return apply(function from(key) {
|
|
179
|
-
const parent = this;
|
|
180
179
|
const { subject, state } = this;
|
|
181
180
|
const required = arg2 === true || arg1 === true;
|
|
182
181
|
let getSource;
|
|
@@ -197,14 +196,13 @@ function from(source, arg1, arg2) {
|
|
|
197
196
|
else
|
|
198
197
|
throw Oops$a.BadSource(subject, key, source);
|
|
199
198
|
const setter = arg1;
|
|
200
|
-
const info = { key, parent
|
|
199
|
+
const info = { key, parent: this };
|
|
201
200
|
let sub;
|
|
202
|
-
let
|
|
203
|
-
if (!
|
|
204
|
-
|
|
201
|
+
let order = ORDER.get(this);
|
|
202
|
+
if (!order)
|
|
203
|
+
ORDER.set(this, order = []);
|
|
205
204
|
state.set(key, undefined);
|
|
206
|
-
|
|
207
|
-
function compute(initial) {
|
|
205
|
+
const compute = (initial) => {
|
|
208
206
|
try {
|
|
209
207
|
return setter.call(sub.proxy, sub.proxy);
|
|
210
208
|
}
|
|
@@ -212,8 +210,8 @@ function from(source, arg1, arg2) {
|
|
|
212
210
|
Oops$a.Failed(subject, key, initial).warn();
|
|
213
211
|
throw err;
|
|
214
212
|
}
|
|
215
|
-
}
|
|
216
|
-
|
|
213
|
+
};
|
|
214
|
+
const refreshValue = () => {
|
|
217
215
|
let value;
|
|
218
216
|
try {
|
|
219
217
|
value = compute(false);
|
|
@@ -223,26 +221,25 @@ function from(source, arg1, arg2) {
|
|
|
223
221
|
}
|
|
224
222
|
finally {
|
|
225
223
|
if (state.get(key) !== value) {
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
state.set(key, value);
|
|
225
|
+
this.update(key);
|
|
228
226
|
return value;
|
|
229
227
|
}
|
|
230
228
|
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (info.parent !== from)
|
|
237
|
-
update();
|
|
238
|
-
else {
|
|
239
|
-
const after = pending.findIndex(peer => (info.priority > INFO.get(peer).priority));
|
|
240
|
-
pending.splice(after + 1, 0, update);
|
|
229
|
+
};
|
|
230
|
+
const dependancyDidUpdate = (_key, source) => {
|
|
231
|
+
if (source !== this) {
|
|
232
|
+
refreshValue();
|
|
233
|
+
return;
|
|
241
234
|
}
|
|
242
|
-
|
|
243
|
-
|
|
235
|
+
let pending = KEYS.get(this);
|
|
236
|
+
if (!pending)
|
|
237
|
+
KEYS.set(this, pending = []);
|
|
238
|
+
pending.push(refreshValue);
|
|
239
|
+
};
|
|
240
|
+
const create = () => {
|
|
244
241
|
const control = getSource();
|
|
245
|
-
sub = control.subscribe(
|
|
242
|
+
sub = control.subscribe(dependancyDidUpdate);
|
|
246
243
|
try {
|
|
247
244
|
const value = compute(true);
|
|
248
245
|
state.set(key, value);
|
|
@@ -253,14 +250,10 @@ function from(source, arg1, arg2) {
|
|
|
253
250
|
}
|
|
254
251
|
finally {
|
|
255
252
|
sub.commit();
|
|
256
|
-
|
|
257
|
-
const peer = register.get(key);
|
|
258
|
-
if (peer && peer.priority >= info.priority)
|
|
259
|
-
info.priority = peer.priority + 1;
|
|
260
|
-
}
|
|
253
|
+
order.push(refreshValue);
|
|
261
254
|
}
|
|
262
|
-
}
|
|
263
|
-
INFO.set(
|
|
255
|
+
};
|
|
256
|
+
INFO.set(refreshValue, info);
|
|
264
257
|
return () => {
|
|
265
258
|
const value = sub ? state.get(key) : create();
|
|
266
259
|
if (value === undefined && required)
|
|
@@ -273,8 +266,11 @@ function flush(control) {
|
|
|
273
266
|
const pending = KEYS.get(control);
|
|
274
267
|
if (!pending)
|
|
275
268
|
return;
|
|
269
|
+
const list = ORDER.get(control);
|
|
276
270
|
while (pending.length) {
|
|
277
|
-
const compute = pending
|
|
271
|
+
const compute = pending
|
|
272
|
+
.sort((a, b) => list.indexOf(b) - list.indexOf(a))
|
|
273
|
+
.pop();
|
|
278
274
|
const { key } = INFO.get(compute);
|
|
279
275
|
if (!control.frame.has(key))
|
|
280
276
|
compute();
|
|
@@ -299,13 +295,17 @@ class Subscriber {
|
|
|
299
295
|
}
|
|
300
296
|
});
|
|
301
297
|
const release = parent.addListener(key => {
|
|
302
|
-
if (!this.active
|
|
298
|
+
if (!this.active)
|
|
303
299
|
return;
|
|
304
300
|
const handler = using.get(key);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
301
|
+
let notify;
|
|
302
|
+
if (typeof handler == "function") {
|
|
303
|
+
const callback = handler();
|
|
304
|
+
if (callback === true)
|
|
305
|
+
notify = this.onUpdate(key, parent);
|
|
306
|
+
}
|
|
307
|
+
else if (handler === true)
|
|
308
|
+
notify = this.onUpdate(key, parent);
|
|
309
309
|
const getWhy = () => {
|
|
310
310
|
const update = getUpdate(parent.subject);
|
|
311
311
|
const applicable = update.filter(k => using.has(k));
|
|
@@ -326,7 +326,7 @@ class Subscriber {
|
|
|
326
326
|
release();
|
|
327
327
|
};
|
|
328
328
|
this.add = (key, value) => {
|
|
329
|
-
if (value)
|
|
329
|
+
if (value !== undefined)
|
|
330
330
|
using.set(key, value);
|
|
331
331
|
else if (!using.has(key))
|
|
332
332
|
using.set(key, true);
|
|
@@ -400,17 +400,15 @@ class Controller {
|
|
|
400
400
|
else if (!frame.size)
|
|
401
401
|
setTimeout(() => {
|
|
402
402
|
flush(this);
|
|
403
|
-
|
|
404
|
-
const keys = Array.from(frame);
|
|
405
|
-
frame.clear();
|
|
406
|
-
waiting.clear();
|
|
407
|
-
UPDATE.set(subject, keys);
|
|
403
|
+
UPDATE.set(subject, Array.from(frame));
|
|
408
404
|
setTimeout(() => {
|
|
409
405
|
UPDATE.delete(subject);
|
|
410
406
|
}, 0);
|
|
411
|
-
|
|
407
|
+
frame.clear();
|
|
408
|
+
for (const notify of waiting)
|
|
412
409
|
try {
|
|
413
|
-
|
|
410
|
+
waiting.delete(notify);
|
|
411
|
+
notify();
|
|
414
412
|
}
|
|
415
413
|
catch (err) {
|
|
416
414
|
console.error(err);
|
|
@@ -661,6 +659,14 @@ function apply(fn, label) {
|
|
|
661
659
|
const desc = output;
|
|
662
660
|
if ("value" in desc)
|
|
663
661
|
state.set(key, desc.value);
|
|
662
|
+
if ("destroy" in output) {
|
|
663
|
+
const { destroy } = output;
|
|
664
|
+
if (destroy)
|
|
665
|
+
this.addListener((key) => {
|
|
666
|
+
if (key == null)
|
|
667
|
+
destroy();
|
|
668
|
+
});
|
|
669
|
+
}
|
|
664
670
|
const { get: onGet, set: onSet, enumerable, suspense } = desc;
|
|
665
671
|
const set = onSet !== false
|
|
666
672
|
? this.ref(key, onSet)
|
|
@@ -940,192 +946,217 @@ function parent(Expects, required) {
|
|
|
940
946
|
|
|
941
947
|
const ANY$1 = Symbol("any");
|
|
942
948
|
function managedMap(control, property, initial) {
|
|
943
|
-
const
|
|
949
|
+
const managed = new ManagedMap(initial, emit);
|
|
944
950
|
const context = new WeakMap();
|
|
945
|
-
const
|
|
946
|
-
|
|
947
|
-
let value;
|
|
951
|
+
const observers = new Set();
|
|
952
|
+
const frozen = new Set();
|
|
948
953
|
function reset() {
|
|
949
|
-
|
|
954
|
+
frozen.clear();
|
|
950
955
|
}
|
|
951
956
|
function emit(key) {
|
|
952
|
-
|
|
957
|
+
observers.forEach(notify => notify(key));
|
|
953
958
|
control.update(property);
|
|
954
959
|
control.waiting.add(reset);
|
|
955
960
|
}
|
|
956
|
-
function
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
emit(k);
|
|
969
|
-
return value.set(k, v);
|
|
970
|
-
};
|
|
971
|
-
managed.delete = (k) => {
|
|
972
|
-
emit(k);
|
|
973
|
-
return value.delete(k);
|
|
974
|
-
};
|
|
975
|
-
managed.clear = () => {
|
|
976
|
-
emit(ANY$1);
|
|
977
|
-
value.clear();
|
|
978
|
-
};
|
|
979
|
-
managed.get = function (key) {
|
|
980
|
-
watch(key, this);
|
|
981
|
-
return value.get(key);
|
|
982
|
-
};
|
|
983
|
-
managed.has = function (key) {
|
|
984
|
-
watch(key, this);
|
|
985
|
-
return value.has(key);
|
|
986
|
-
};
|
|
987
|
-
managed.values = function () {
|
|
988
|
-
watch(ANY$1, this);
|
|
989
|
-
return value.values();
|
|
990
|
-
};
|
|
991
|
-
managed.keys = function () {
|
|
992
|
-
watch(ANY$1, this);
|
|
993
|
-
return value.keys();
|
|
994
|
-
};
|
|
995
|
-
managed.entries = function () {
|
|
996
|
-
watch(ANY$1, this);
|
|
997
|
-
return value.entries();
|
|
998
|
-
};
|
|
999
|
-
managed[Symbol.iterator] = function () {
|
|
1000
|
-
watch(ANY$1, this);
|
|
1001
|
-
return value[Symbol.iterator]();
|
|
1002
|
-
};
|
|
1003
|
-
defineProperty(managed, "size", {
|
|
1004
|
-
get() {
|
|
1005
|
-
watch(ANY$1, this);
|
|
1006
|
-
return value.size;
|
|
961
|
+
function init(local) {
|
|
962
|
+
const proxy = create(managed);
|
|
963
|
+
const using = new Set();
|
|
964
|
+
observers.add(key => {
|
|
965
|
+
if (frozen.has(local))
|
|
966
|
+
return;
|
|
967
|
+
if (using.has(key) || using.has(ANY$1) || key === ANY$1 && using.size) {
|
|
968
|
+
const refresh = local.onUpdate(property, control);
|
|
969
|
+
if (refresh) {
|
|
970
|
+
frozen.add(local);
|
|
971
|
+
refresh();
|
|
972
|
+
}
|
|
1007
973
|
}
|
|
1008
974
|
});
|
|
1009
|
-
|
|
1010
|
-
function getValue(local) {
|
|
1011
|
-
if (!local)
|
|
1012
|
-
return managed;
|
|
1013
|
-
if (context.has(local))
|
|
1014
|
-
return context.get(local);
|
|
1015
|
-
const proxy = Object.create(managed);
|
|
1016
|
-
const using = new Set();
|
|
975
|
+
local.add(property, false);
|
|
1017
976
|
context.set(local, proxy);
|
|
1018
|
-
|
|
977
|
+
proxy.watch = (key) => {
|
|
1019
978
|
if (!local.active)
|
|
1020
979
|
using.add(key);
|
|
1021
|
-
}
|
|
1022
|
-
local.add(property, () => {
|
|
1023
|
-
if (using.has(ANY$1) || lastUpdate.has(ANY$1) && using.size)
|
|
1024
|
-
return true;
|
|
1025
|
-
for (const key of lastUpdate)
|
|
1026
|
-
if (using.has(key))
|
|
1027
|
-
return true;
|
|
1028
|
-
});
|
|
980
|
+
};
|
|
1029
981
|
return proxy;
|
|
1030
982
|
}
|
|
1031
|
-
setValue(initial, true);
|
|
1032
983
|
return {
|
|
1033
|
-
|
|
1034
|
-
get
|
|
984
|
+
value: initial,
|
|
985
|
+
get(local) {
|
|
986
|
+
if (!local)
|
|
987
|
+
return managed;
|
|
988
|
+
if (context.has(local))
|
|
989
|
+
return context.get(local);
|
|
990
|
+
return init(local);
|
|
991
|
+
},
|
|
992
|
+
set(next) {
|
|
993
|
+
managed.source = next;
|
|
994
|
+
control.state.set(property, next);
|
|
995
|
+
emit(ANY$1);
|
|
996
|
+
},
|
|
997
|
+
destroy() {
|
|
998
|
+
observers.clear();
|
|
999
|
+
}
|
|
1035
1000
|
};
|
|
1001
|
+
}
|
|
1002
|
+
class ManagedMap {
|
|
1003
|
+
constructor(source, emit) {
|
|
1004
|
+
this.source = source;
|
|
1005
|
+
this.emit = emit;
|
|
1006
|
+
}
|
|
1007
|
+
watch(_key) { }
|
|
1008
|
+
set(key, value) {
|
|
1009
|
+
this.source.set(key, value);
|
|
1010
|
+
this.emit(key);
|
|
1011
|
+
return this;
|
|
1012
|
+
}
|
|
1013
|
+
;
|
|
1014
|
+
delete(key) {
|
|
1015
|
+
this.emit(key);
|
|
1016
|
+
return this.source.delete(key);
|
|
1017
|
+
}
|
|
1018
|
+
;
|
|
1019
|
+
clear() {
|
|
1020
|
+
this.emit(ANY$1);
|
|
1021
|
+
this.source.clear();
|
|
1022
|
+
}
|
|
1023
|
+
get(key) {
|
|
1024
|
+
this.watch(key);
|
|
1025
|
+
return this.source.get(key);
|
|
1026
|
+
}
|
|
1027
|
+
;
|
|
1028
|
+
has(key) {
|
|
1029
|
+
this.watch(key);
|
|
1030
|
+
return this.source.has(key);
|
|
1031
|
+
}
|
|
1032
|
+
;
|
|
1033
|
+
values() {
|
|
1034
|
+
this.watch(ANY$1);
|
|
1035
|
+
return this.source.values();
|
|
1036
|
+
}
|
|
1037
|
+
keys() {
|
|
1038
|
+
this.watch(ANY$1);
|
|
1039
|
+
return this.source.keys();
|
|
1040
|
+
}
|
|
1041
|
+
entries() {
|
|
1042
|
+
this.watch(ANY$1);
|
|
1043
|
+
return this.source.entries();
|
|
1044
|
+
}
|
|
1045
|
+
;
|
|
1046
|
+
[Symbol.iterator]() {
|
|
1047
|
+
this.watch(ANY$1);
|
|
1048
|
+
return this.source[Symbol.iterator]();
|
|
1049
|
+
}
|
|
1050
|
+
;
|
|
1051
|
+
get size() {
|
|
1052
|
+
this.watch(ANY$1);
|
|
1053
|
+
return this.source.size;
|
|
1054
|
+
}
|
|
1036
1055
|
}
|
|
1037
1056
|
|
|
1038
1057
|
const ANY = Symbol("any");
|
|
1039
1058
|
function managedSet(control, property, initial) {
|
|
1040
|
-
const
|
|
1059
|
+
const managed = new ManagedSet(initial, emit);
|
|
1041
1060
|
const context = new WeakMap();
|
|
1042
|
-
const
|
|
1043
|
-
|
|
1044
|
-
let value;
|
|
1061
|
+
const observers = new Set();
|
|
1062
|
+
const frozen = new Set();
|
|
1045
1063
|
function reset() {
|
|
1046
|
-
|
|
1064
|
+
frozen.clear();
|
|
1047
1065
|
}
|
|
1048
1066
|
function emit(key) {
|
|
1049
|
-
|
|
1067
|
+
observers.forEach(notify => notify(key));
|
|
1050
1068
|
control.update(property);
|
|
1051
1069
|
control.waiting.add(reset);
|
|
1052
1070
|
}
|
|
1053
|
-
function
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
emit(k);
|
|
1066
|
-
return value.add(k);
|
|
1067
|
-
};
|
|
1068
|
-
managed.delete = (k) => {
|
|
1069
|
-
emit(k);
|
|
1070
|
-
return value.delete(k);
|
|
1071
|
-
};
|
|
1072
|
-
managed.clear = () => {
|
|
1073
|
-
emit(ANY);
|
|
1074
|
-
value.clear();
|
|
1075
|
-
};
|
|
1076
|
-
managed.has = function (key) {
|
|
1077
|
-
watch(key, this);
|
|
1078
|
-
return value.has(key);
|
|
1079
|
-
};
|
|
1080
|
-
managed.values = function () {
|
|
1081
|
-
watch(ANY, this);
|
|
1082
|
-
return value.values();
|
|
1083
|
-
};
|
|
1084
|
-
managed.keys = function () {
|
|
1085
|
-
watch(ANY, this);
|
|
1086
|
-
return value.keys();
|
|
1087
|
-
};
|
|
1088
|
-
managed.entries = function () {
|
|
1089
|
-
watch(ANY, this);
|
|
1090
|
-
return value.entries();
|
|
1091
|
-
};
|
|
1092
|
-
managed[Symbol.iterator] = function () {
|
|
1093
|
-
watch(ANY, this);
|
|
1094
|
-
return value[Symbol.iterator]();
|
|
1095
|
-
};
|
|
1096
|
-
defineProperty(managed, "size", {
|
|
1097
|
-
get() {
|
|
1098
|
-
watch(ANY, this);
|
|
1099
|
-
return value.size;
|
|
1071
|
+
function init(local) {
|
|
1072
|
+
const proxy = create(managed);
|
|
1073
|
+
const using = new Set();
|
|
1074
|
+
observers.add(key => {
|
|
1075
|
+
if (frozen.has(local))
|
|
1076
|
+
return;
|
|
1077
|
+
if (using.has(key) || using.has(ANY) || key === ANY && using.size) {
|
|
1078
|
+
const refresh = local.onUpdate(property, control);
|
|
1079
|
+
if (refresh) {
|
|
1080
|
+
frozen.add(local);
|
|
1081
|
+
refresh();
|
|
1082
|
+
}
|
|
1100
1083
|
}
|
|
1101
1084
|
});
|
|
1102
|
-
|
|
1103
|
-
function getValue(local) {
|
|
1104
|
-
if (!local)
|
|
1105
|
-
return managed;
|
|
1106
|
-
if (context.has(local))
|
|
1107
|
-
return context.get(local);
|
|
1108
|
-
const proxy = Object.create(managed);
|
|
1109
|
-
const using = new Set();
|
|
1085
|
+
local.add(property, false);
|
|
1110
1086
|
context.set(local, proxy);
|
|
1111
|
-
|
|
1087
|
+
proxy.watch = (key) => {
|
|
1112
1088
|
if (!local.active)
|
|
1113
1089
|
using.add(key);
|
|
1114
|
-
}
|
|
1115
|
-
local.add(property, () => {
|
|
1116
|
-
if (using.has(ANY) || lastUpdate.has(ANY) && using.size)
|
|
1117
|
-
return true;
|
|
1118
|
-
for (const key of lastUpdate)
|
|
1119
|
-
if (using.has(key))
|
|
1120
|
-
return true;
|
|
1121
|
-
});
|
|
1090
|
+
};
|
|
1122
1091
|
return proxy;
|
|
1123
1092
|
}
|
|
1124
|
-
setValue(initial, true);
|
|
1125
1093
|
return {
|
|
1126
|
-
|
|
1127
|
-
get
|
|
1094
|
+
value: initial,
|
|
1095
|
+
get(local) {
|
|
1096
|
+
if (!local)
|
|
1097
|
+
return managed;
|
|
1098
|
+
if (context.has(local))
|
|
1099
|
+
return context.get(local);
|
|
1100
|
+
return init(local);
|
|
1101
|
+
},
|
|
1102
|
+
set(next) {
|
|
1103
|
+
managed.source = next;
|
|
1104
|
+
control.state.set(property, next);
|
|
1105
|
+
emit(ANY);
|
|
1106
|
+
},
|
|
1107
|
+
destroy() {
|
|
1108
|
+
observers.clear();
|
|
1109
|
+
}
|
|
1128
1110
|
};
|
|
1111
|
+
}
|
|
1112
|
+
class ManagedSet {
|
|
1113
|
+
constructor(source, emit) {
|
|
1114
|
+
this.source = source;
|
|
1115
|
+
this.emit = emit;
|
|
1116
|
+
}
|
|
1117
|
+
watch(_key) { }
|
|
1118
|
+
add(key) {
|
|
1119
|
+
this.source.add(key);
|
|
1120
|
+
this.emit(key);
|
|
1121
|
+
return this;
|
|
1122
|
+
}
|
|
1123
|
+
;
|
|
1124
|
+
delete(key) {
|
|
1125
|
+
this.emit(key);
|
|
1126
|
+
return this.source.delete(key);
|
|
1127
|
+
}
|
|
1128
|
+
;
|
|
1129
|
+
clear() {
|
|
1130
|
+
this.emit(ANY);
|
|
1131
|
+
this.source.clear();
|
|
1132
|
+
}
|
|
1133
|
+
has(key) {
|
|
1134
|
+
this.watch(key);
|
|
1135
|
+
return this.source.has(key);
|
|
1136
|
+
}
|
|
1137
|
+
;
|
|
1138
|
+
values() {
|
|
1139
|
+
this.watch(ANY);
|
|
1140
|
+
return this.source.values();
|
|
1141
|
+
}
|
|
1142
|
+
keys() {
|
|
1143
|
+
this.watch(ANY);
|
|
1144
|
+
return this.source.keys();
|
|
1145
|
+
}
|
|
1146
|
+
entries() {
|
|
1147
|
+
this.watch(ANY);
|
|
1148
|
+
return this.source.entries();
|
|
1149
|
+
}
|
|
1150
|
+
;
|
|
1151
|
+
[Symbol.iterator]() {
|
|
1152
|
+
this.watch(ANY);
|
|
1153
|
+
return this.source[Symbol.iterator]();
|
|
1154
|
+
}
|
|
1155
|
+
;
|
|
1156
|
+
get size() {
|
|
1157
|
+
this.watch(ANY);
|
|
1158
|
+
return this.source.size;
|
|
1159
|
+
}
|
|
1129
1160
|
}
|
|
1130
1161
|
|
|
1131
1162
|
const Oops$5 = issues({
|