@expressive/mvc 0.8.0 → 0.8.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 +21 -18
- package/lib/index.esm.js +65 -66
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +65 -66
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -195,20 +195,21 @@ class Subscriber {
|
|
|
195
195
|
this.onUpdate = onUpdate;
|
|
196
196
|
this.active = false;
|
|
197
197
|
this.dependant = new Set();
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
198
|
+
this.watch = new Map();
|
|
199
|
+
this.commit = () => {
|
|
200
|
+
const release = this.parent.addListener(this.event);
|
|
201
|
+
this.active = true;
|
|
202
|
+
this.dependant.forEach(x => x.commit());
|
|
203
|
+
return this.release = () => {
|
|
204
|
+
this.dependant.forEach(x => x.release());
|
|
205
|
+
release();
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
this.event = (key) => {
|
|
209
209
|
if (!this.active)
|
|
210
210
|
return;
|
|
211
|
-
const
|
|
211
|
+
const { parent, watch } = this;
|
|
212
|
+
const handler = watch.get(key);
|
|
212
213
|
let notify;
|
|
213
214
|
if (typeof handler == "function") {
|
|
214
215
|
const callback = handler();
|
|
@@ -219,49 +220,47 @@ class Subscriber {
|
|
|
219
220
|
notify = this.onUpdate(key, parent);
|
|
220
221
|
if (!notify)
|
|
221
222
|
return;
|
|
222
|
-
parent.waiting.add(() =>
|
|
223
|
+
parent.waiting.add(() => {
|
|
224
|
+
this.latest = parent.latest.filter(k => watch.has(k));
|
|
225
|
+
});
|
|
223
226
|
parent.waiting.add(notify);
|
|
224
|
-
});
|
|
225
|
-
this.add = (key, value) => {
|
|
226
|
-
if (value !== undefined)
|
|
227
|
-
using.set(key, value);
|
|
228
|
-
else if (!using.has(key))
|
|
229
|
-
using.set(key, true);
|
|
230
|
-
};
|
|
231
|
-
this.commit = () => {
|
|
232
|
-
this.active = true;
|
|
233
|
-
this.dependant.forEach(x => x.commit());
|
|
234
|
-
return this.release;
|
|
235
|
-
};
|
|
236
|
-
this.release = () => {
|
|
237
|
-
this.dependant.forEach(x => x.release());
|
|
238
|
-
release();
|
|
239
227
|
};
|
|
228
|
+
const proxy = create(parent.subject);
|
|
229
|
+
const reset = () => this.latest = undefined;
|
|
230
|
+
REGISTER$1.set(proxy, this);
|
|
231
|
+
defineProperty(this, "proxy", {
|
|
232
|
+
configurable: true,
|
|
233
|
+
get() {
|
|
234
|
+
setTimeout(reset, 0);
|
|
235
|
+
return proxy;
|
|
236
|
+
}
|
|
237
|
+
});
|
|
240
238
|
}
|
|
241
239
|
static get(from) {
|
|
242
240
|
return REGISTER$1.get(from);
|
|
243
241
|
}
|
|
242
|
+
get using() {
|
|
243
|
+
return Array.from(this.watch.keys());
|
|
244
|
+
}
|
|
245
|
+
assign(apply, keys) {
|
|
246
|
+
const { waiting, subject } = this.parent;
|
|
247
|
+
this.active = false;
|
|
248
|
+
if (typeof keys !== "object")
|
|
249
|
+
keys = getOwnPropertyNames(subject);
|
|
250
|
+
for (const key of keys)
|
|
251
|
+
if (key in apply)
|
|
252
|
+
subject[key] = apply[key];
|
|
253
|
+
waiting.add(() => this.active = true);
|
|
254
|
+
}
|
|
255
|
+
add(key, value) {
|
|
256
|
+
if (value !== undefined)
|
|
257
|
+
this.watch.set(key, value);
|
|
258
|
+
else if (!this.watch.has(key))
|
|
259
|
+
this.watch.set(key, true);
|
|
260
|
+
}
|
|
244
261
|
}
|
|
245
262
|
|
|
246
263
|
const REGISTER = new WeakMap();
|
|
247
|
-
const UPDATE$1 = new WeakMap();
|
|
248
|
-
function getUpdate(subject) {
|
|
249
|
-
return UPDATE$1.get(subject);
|
|
250
|
-
}
|
|
251
|
-
function setUpdate(subject, keys) {
|
|
252
|
-
UPDATE$1.set(subject, Array.from(keys));
|
|
253
|
-
setTimeout(() => UPDATE$1.delete(subject), 0);
|
|
254
|
-
}
|
|
255
|
-
/** Ensure a local update is dropped after use. */
|
|
256
|
-
function hasUpdate(proxy) {
|
|
257
|
-
if (UPDATE$1.has(proxy))
|
|
258
|
-
setTimeout(() => UPDATE$1.delete(proxy), 0);
|
|
259
|
-
}
|
|
260
|
-
/** Set local update for a subscribed context. */
|
|
261
|
-
function addUpdate(proxy, using) {
|
|
262
|
-
const parent = UPDATE$1.get(getPrototypeOf(proxy));
|
|
263
|
-
UPDATE$1.set(proxy, parent.filter(k => using.has(k)));
|
|
264
|
-
}
|
|
265
264
|
class Control {
|
|
266
265
|
constructor(subject) {
|
|
267
266
|
this.subject = subject;
|
|
@@ -328,7 +327,8 @@ class Control {
|
|
|
328
327
|
else if (!frame.size)
|
|
329
328
|
setTimeout(() => {
|
|
330
329
|
flush(this);
|
|
331
|
-
|
|
330
|
+
this.latest = Array.from(frame);
|
|
331
|
+
setTimeout(() => this.latest = undefined, 0);
|
|
332
332
|
frame.clear();
|
|
333
333
|
for (const notify of waiting)
|
|
334
334
|
try {
|
|
@@ -379,12 +379,16 @@ class Control {
|
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
const PENDING = new Map();
|
|
382
|
-
|
|
383
|
-
|
|
382
|
+
/**
|
|
383
|
+
* Run instruction as controller sets itself up.
|
|
384
|
+
* This will specialize the behavior of a given property.
|
|
385
|
+
*/
|
|
386
|
+
function add(instruction, label) {
|
|
387
|
+
const name = label || instruction.name || "pending";
|
|
384
388
|
const placeholder = Symbol(`${name} instruction`);
|
|
385
389
|
function setup(key) {
|
|
386
390
|
const { subject, state } = this;
|
|
387
|
-
let output =
|
|
391
|
+
let output = instruction.call(this, key, this);
|
|
388
392
|
if (typeof output == "function")
|
|
389
393
|
output = { get: output };
|
|
390
394
|
if (typeof output != "object")
|
|
@@ -937,7 +941,7 @@ class Model {
|
|
|
937
941
|
}
|
|
938
942
|
else if (keys.includes(key)) {
|
|
939
943
|
removeListener();
|
|
940
|
-
return () => resolve(single ? control.state.get(key) :
|
|
944
|
+
return () => resolve(single ? control.state.get(key) : control.latest);
|
|
941
945
|
}
|
|
942
946
|
});
|
|
943
947
|
});
|
|
@@ -957,7 +961,7 @@ class Model {
|
|
|
957
961
|
catch (e) { }
|
|
958
962
|
const callback = single
|
|
959
963
|
? () => { argument.call(this, control.state.get(select), select); }
|
|
960
|
-
: () => { argument.call(this,
|
|
964
|
+
: () => { argument.call(this, control.latest); };
|
|
961
965
|
const onEvent = once
|
|
962
966
|
? () => {
|
|
963
967
|
removeListener();
|
|
@@ -1042,7 +1046,7 @@ class Model {
|
|
|
1042
1046
|
throw Oops$5.NoChaining();
|
|
1043
1047
|
if (frame.size || arg1 !== false)
|
|
1044
1048
|
waiting.add(() => {
|
|
1045
|
-
callback(
|
|
1049
|
+
callback(control.latest);
|
|
1046
1050
|
});
|
|
1047
1051
|
else
|
|
1048
1052
|
callback(false);
|
|
@@ -1235,14 +1239,8 @@ function useModel(source, arg, arg2) {
|
|
|
1235
1239
|
return instance;
|
|
1236
1240
|
}
|
|
1237
1241
|
const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
|
|
1238
|
-
if (typeof arg == "object")
|
|
1239
|
-
local.
|
|
1240
|
-
if (typeof arg2 !== "object")
|
|
1241
|
-
arg2 = getOwnPropertyNames(instance);
|
|
1242
|
-
for (const key of arg2)
|
|
1243
|
-
if (key in arg)
|
|
1244
|
-
instance[key] = arg[key];
|
|
1245
|
-
}
|
|
1242
|
+
if (typeof arg == "object")
|
|
1243
|
+
local.assign(arg, arg2);
|
|
1246
1244
|
React__default["default"].useLayoutEffect(() => {
|
|
1247
1245
|
local.commit();
|
|
1248
1246
|
return () => {
|
|
@@ -1332,10 +1330,10 @@ class MVC extends Model {
|
|
|
1332
1330
|
}
|
|
1333
1331
|
}
|
|
1334
1332
|
|
|
1335
|
-
const LOCAL =
|
|
1336
|
-
const STATE =
|
|
1337
|
-
const UPDATE =
|
|
1338
|
-
const CONTROL =
|
|
1333
|
+
const LOCAL = "$debug local";
|
|
1334
|
+
const STATE = "$debug state";
|
|
1335
|
+
const UPDATE = "$debug update";
|
|
1336
|
+
const CONTROL = "$debug controller";
|
|
1339
1337
|
Object.defineProperties(Model.prototype, {
|
|
1340
1338
|
[CONTROL]: {
|
|
1341
1339
|
get() {
|
|
@@ -1357,7 +1355,8 @@ Object.defineProperties(Model.prototype, {
|
|
|
1357
1355
|
},
|
|
1358
1356
|
[UPDATE]: {
|
|
1359
1357
|
get() {
|
|
1360
|
-
|
|
1358
|
+
const source = Subscriber.get(this) || Control.get(this);
|
|
1359
|
+
return source && source.latest;
|
|
1361
1360
|
}
|
|
1362
1361
|
}
|
|
1363
1362
|
});
|