@expressive/mvc 0.48.0 → 0.50.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/dist/index.d.ts +33 -24
- package/dist/index.js +272 -240
- package/dist/index.mjs +268 -237
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -7,79 +7,66 @@ function addListener(subject, callback, select) {
|
|
|
7
7
|
let subs = LISTENER.get(subject);
|
|
8
8
|
if (!subs)
|
|
9
9
|
LISTENER.set(subject, subs = /* @__PURE__ */ new Map([[onReady, false]]));
|
|
10
|
-
const filter =
|
|
10
|
+
const filter = select !== void 0 && /* @__PURE__ */ new Set([select]);
|
|
11
11
|
if (!filter && !subs.has(onReady))
|
|
12
12
|
callback(true, subject);
|
|
13
13
|
subs.set(callback, filter);
|
|
14
14
|
return () => subs.delete(callback);
|
|
15
15
|
}
|
|
16
|
-
function watch(from,
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const listeners = LISTENER.get(from);
|
|
20
|
-
listeners.set(
|
|
21
|
-
observer,
|
|
22
|
-
(listeners.get(observer) || /* @__PURE__ */ new Set()).add(key)
|
|
23
|
-
);
|
|
24
|
-
const nested = LISTENER.get(value);
|
|
25
|
-
if (nested) {
|
|
26
|
-
LISTENER.set(value = Object.create(value), nested);
|
|
27
|
-
OBSERVER.set(value, observer);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return value;
|
|
16
|
+
function watch(from, key2, value) {
|
|
17
|
+
const access = OBSERVER.get(from);
|
|
18
|
+
return access ? access(from, key2, value) : value;
|
|
31
19
|
}
|
|
32
20
|
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
33
|
-
function
|
|
21
|
+
function emit(source, key2) {
|
|
34
22
|
const subs = LISTENER.get(source);
|
|
35
23
|
const ready = !subs.has(onReady);
|
|
36
|
-
if (
|
|
24
|
+
if (key2 === true && ready)
|
|
37
25
|
return;
|
|
38
26
|
let pending = PENDING.get(source);
|
|
39
27
|
if (pending) {
|
|
40
|
-
pending.add(
|
|
28
|
+
pending.add(key2);
|
|
41
29
|
return;
|
|
42
30
|
}
|
|
43
31
|
PENDING.set(source, pending = new Set(
|
|
44
|
-
|
|
32
|
+
key2 !== true && ready ? [key2] : [true, key2]
|
|
45
33
|
));
|
|
46
|
-
pending.forEach((
|
|
47
|
-
pending.delete(
|
|
34
|
+
pending.forEach((key3) => {
|
|
35
|
+
pending.delete(key3);
|
|
48
36
|
subs.forEach((select, callback) => {
|
|
49
37
|
let after;
|
|
50
|
-
if (!select || select.has(
|
|
51
|
-
if (after = callback.call(source,
|
|
38
|
+
if (!select || select.has(key3)) {
|
|
39
|
+
if (after = callback.call(source, key3, source))
|
|
52
40
|
queue(after);
|
|
53
41
|
}
|
|
54
|
-
if (after === null ||
|
|
42
|
+
if (after === null || key3 === null)
|
|
55
43
|
subs.delete(callback);
|
|
56
44
|
});
|
|
57
45
|
});
|
|
58
46
|
PENDING.delete(source);
|
|
59
47
|
}
|
|
60
|
-
function queue(
|
|
48
|
+
function queue(event) {
|
|
61
49
|
if (!DISPATCH.size)
|
|
62
50
|
setTimeout(() => {
|
|
63
|
-
DISPATCH.forEach((
|
|
51
|
+
DISPATCH.forEach((event2) => {
|
|
64
52
|
try {
|
|
65
|
-
|
|
53
|
+
event2();
|
|
66
54
|
} catch (err) {
|
|
67
55
|
console.error(err);
|
|
68
56
|
}
|
|
69
57
|
});
|
|
70
58
|
DISPATCH.clear();
|
|
71
59
|
}, 0);
|
|
72
|
-
DISPATCH.add(
|
|
60
|
+
DISPATCH.add(event);
|
|
73
61
|
}
|
|
74
|
-
function effect(target, callback) {
|
|
62
|
+
function effect(target, callback, requireValues) {
|
|
75
63
|
const listeners = LISTENER.get(target);
|
|
76
64
|
let unset;
|
|
77
65
|
let reset;
|
|
78
66
|
function invoke() {
|
|
79
67
|
let stale;
|
|
80
68
|
const subscriber = Object.create(target);
|
|
81
|
-
|
|
82
|
-
OBSERVER.set(subscriber, () => {
|
|
69
|
+
function onUpdate() {
|
|
83
70
|
if (stale)
|
|
84
71
|
return null;
|
|
85
72
|
stale = true;
|
|
@@ -88,7 +75,24 @@ function effect(target, callback) {
|
|
|
88
75
|
unset = void 0;
|
|
89
76
|
}
|
|
90
77
|
return reset;
|
|
91
|
-
}
|
|
78
|
+
}
|
|
79
|
+
function access(from, key2, value) {
|
|
80
|
+
if (value === void 0 && requireValues)
|
|
81
|
+
throw new Error(`${from}.${key2} is required in this context.`);
|
|
82
|
+
const listeners2 = LISTENER.get(from);
|
|
83
|
+
let listener = listeners2.get(onUpdate);
|
|
84
|
+
if (!listener)
|
|
85
|
+
listeners2.set(onUpdate, listener = /* @__PURE__ */ new Set());
|
|
86
|
+
listener.add(key2);
|
|
87
|
+
const nested = LISTENER.get(value);
|
|
88
|
+
if (nested) {
|
|
89
|
+
LISTENER.set(value = Object.create(value), nested);
|
|
90
|
+
OBSERVER.set(value, access);
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
LISTENER.set(subscriber, listeners);
|
|
95
|
+
OBSERVER.set(subscriber, access);
|
|
92
96
|
try {
|
|
93
97
|
const out = callback.call(subscriber, subscriber);
|
|
94
98
|
unset = typeof out == "function" ? out : void 0;
|
|
@@ -101,12 +105,12 @@ function effect(target, callback) {
|
|
|
101
105
|
throw err;
|
|
102
106
|
}
|
|
103
107
|
}
|
|
104
|
-
addListener(target, (
|
|
105
|
-
if (
|
|
108
|
+
addListener(target, (key2) => {
|
|
109
|
+
if (key2 === true)
|
|
106
110
|
invoke();
|
|
107
111
|
else if (!reset)
|
|
108
112
|
return reset;
|
|
109
|
-
if (
|
|
113
|
+
if (key2 === null && unset)
|
|
110
114
|
unset(null);
|
|
111
115
|
});
|
|
112
116
|
return () => {
|
|
@@ -160,15 +164,15 @@ var Model = class _Model {
|
|
|
160
164
|
}
|
|
161
165
|
done = cleanup;
|
|
162
166
|
})();
|
|
163
|
-
for (const
|
|
164
|
-
const desc = Object.getOwnPropertyDescriptor(this,
|
|
167
|
+
for (const key2 in this) {
|
|
168
|
+
const desc = Object.getOwnPropertyDescriptor(this, key2);
|
|
165
169
|
if ("value" in desc) {
|
|
166
|
-
update(this,
|
|
167
|
-
define(this,
|
|
170
|
+
update(this, key2, desc.value, true);
|
|
171
|
+
define(this, key2, {
|
|
168
172
|
configurable: false,
|
|
169
|
-
set: (x) => update(this,
|
|
173
|
+
set: (x) => update(this, key2, x),
|
|
170
174
|
get() {
|
|
171
|
-
return watch(this,
|
|
175
|
+
return watch(this, key2, state[key2]);
|
|
172
176
|
}
|
|
173
177
|
});
|
|
174
178
|
}
|
|
@@ -203,12 +207,12 @@ var Model = class _Model {
|
|
|
203
207
|
if (arg1 === void 0) {
|
|
204
208
|
const values = {};
|
|
205
209
|
const current = !EXPORT && (EXPORT = /* @__PURE__ */ new Map([[self, values]]));
|
|
206
|
-
for (let [
|
|
210
|
+
for (let [key2, value] of self) {
|
|
207
211
|
if (EXPORT.has(value))
|
|
208
212
|
value = EXPORT.get(value);
|
|
209
213
|
else if (value && typeof value.get === "function")
|
|
210
214
|
EXPORT.set(value, value = value.get());
|
|
211
|
-
values[
|
|
215
|
+
values[key2] = value;
|
|
212
216
|
}
|
|
213
217
|
if (current)
|
|
214
218
|
EXPORT = void 0;
|
|
@@ -229,16 +233,16 @@ var Model = class _Model {
|
|
|
229
233
|
set(arg1, arg2, arg3) {
|
|
230
234
|
const self = this.is;
|
|
231
235
|
if (typeof arg1 == "function")
|
|
232
|
-
return addListener(self, (
|
|
233
|
-
if (typeof
|
|
234
|
-
return arg1.call(self,
|
|
236
|
+
return addListener(self, (key2) => {
|
|
237
|
+
if (typeof key2 == "string")
|
|
238
|
+
return arg1.call(self, key2, self);
|
|
235
239
|
});
|
|
236
240
|
if (arg1 === null)
|
|
237
|
-
return
|
|
241
|
+
return emit(this, null);
|
|
238
242
|
if (typeof arg1 == "object")
|
|
239
243
|
assign(self, arg1);
|
|
240
244
|
else if (arg1 == void 0)
|
|
241
|
-
|
|
245
|
+
emit(this, true);
|
|
242
246
|
else if (1 in arguments)
|
|
243
247
|
update(self, arg1, arg2, arg3);
|
|
244
248
|
else
|
|
@@ -246,8 +250,8 @@ var Model = class _Model {
|
|
|
246
250
|
if (PENDING2.has(self))
|
|
247
251
|
return {
|
|
248
252
|
then: (res) => new Promise((res2) => {
|
|
249
|
-
const remove = addListener(self, (
|
|
250
|
-
if (
|
|
253
|
+
const remove = addListener(self, (key2) => {
|
|
254
|
+
if (key2 !== true) {
|
|
251
255
|
remove();
|
|
252
256
|
return res2.bind(null, Array.from(PENDING2.get(self)));
|
|
253
257
|
}
|
|
@@ -268,7 +272,7 @@ var Model = class _Model {
|
|
|
268
272
|
*/
|
|
269
273
|
static new(...args) {
|
|
270
274
|
const instance = new this(...args);
|
|
271
|
-
|
|
275
|
+
emit(instance, true);
|
|
272
276
|
return instance;
|
|
273
277
|
}
|
|
274
278
|
/**
|
|
@@ -310,12 +314,12 @@ function fetch(subject, property, required) {
|
|
|
310
314
|
}
|
|
311
315
|
const error = new Error(`${subject}.${property} is not yet available.`);
|
|
312
316
|
const promise = new Promise((resolve, reject) => {
|
|
313
|
-
addListener(subject, (
|
|
314
|
-
if (
|
|
315
|
-
resolve(state[
|
|
317
|
+
addListener(subject, (key2) => {
|
|
318
|
+
if (key2 === property) {
|
|
319
|
+
resolve(state[key2]);
|
|
316
320
|
return null;
|
|
317
321
|
}
|
|
318
|
-
if (
|
|
322
|
+
if (key2 === null)
|
|
319
323
|
reject(new Error(`${subject} is destroyed.`));
|
|
320
324
|
});
|
|
321
325
|
});
|
|
@@ -326,63 +330,70 @@ function fetch(subject, property, required) {
|
|
|
326
330
|
stack: error.stack
|
|
327
331
|
});
|
|
328
332
|
}
|
|
329
|
-
function update(subject,
|
|
333
|
+
function update(subject, key2, value, arg) {
|
|
330
334
|
const state = STATE.get(subject);
|
|
331
335
|
if (Object.isFrozen(state))
|
|
332
|
-
throw new Error(`Tried to update ${String(
|
|
333
|
-
const previous = state[
|
|
336
|
+
throw new Error(`Tried to update ${String(key2)} but ${subject} is destroyed.`);
|
|
337
|
+
const previous = state[key2];
|
|
338
|
+
if (typeof arg == "function") {
|
|
339
|
+
const out = arg.call(subject, value, previous);
|
|
340
|
+
if (out === false)
|
|
341
|
+
return false;
|
|
342
|
+
if (typeof out == "function")
|
|
343
|
+
value = out();
|
|
344
|
+
}
|
|
334
345
|
if (value === previous)
|
|
335
346
|
return true;
|
|
336
347
|
if (value instanceof Model && !PARENT.has(value)) {
|
|
337
348
|
PARENT.set(value, subject);
|
|
338
|
-
|
|
349
|
+
emit(value, true);
|
|
339
350
|
}
|
|
340
|
-
state[
|
|
341
|
-
if (
|
|
342
|
-
push(subject,
|
|
351
|
+
state[key2] = value;
|
|
352
|
+
if (arg !== true)
|
|
353
|
+
push(subject, key2);
|
|
343
354
|
}
|
|
344
|
-
function push(subject,
|
|
355
|
+
function push(subject, key2, silent) {
|
|
345
356
|
let pending = PENDING2.get(subject);
|
|
346
357
|
if (!pending) {
|
|
347
358
|
PENDING2.set(subject, pending = /* @__PURE__ */ new Set());
|
|
348
359
|
if (!silent)
|
|
349
360
|
queue(() => {
|
|
350
|
-
|
|
361
|
+
emit(subject, false);
|
|
351
362
|
PENDING2.delete(subject);
|
|
352
363
|
});
|
|
353
364
|
}
|
|
354
|
-
pending.add(
|
|
365
|
+
pending.add(key2);
|
|
355
366
|
if (!silent)
|
|
356
|
-
|
|
367
|
+
emit(subject, key2);
|
|
357
368
|
}
|
|
358
369
|
var METHODS = new WeakMap([[Model, []]]);
|
|
359
370
|
function assign(to, values) {
|
|
360
371
|
const methods = METHODS.get(to.constructor);
|
|
361
372
|
const applicable = new Set(Object.keys(to).concat(methods));
|
|
362
|
-
for (const
|
|
363
|
-
if (applicable.has(
|
|
364
|
-
to[
|
|
373
|
+
for (const key2 in values)
|
|
374
|
+
if (applicable.has(key2))
|
|
375
|
+
to[key2] = values[key2];
|
|
365
376
|
}
|
|
366
377
|
function bindMethods(type) {
|
|
367
378
|
let keys = METHODS.get(type);
|
|
368
379
|
if (!keys) {
|
|
369
380
|
METHODS.set(type, keys = bindMethods(Object.getPrototypeOf(type)).slice());
|
|
370
381
|
const desc = Object.getOwnPropertyDescriptors(type.prototype);
|
|
371
|
-
for (const
|
|
372
|
-
if (
|
|
382
|
+
for (const key2 in desc)
|
|
383
|
+
if (key2 != "constructor" && "value" in desc[key2]) {
|
|
373
384
|
let bind2 = function(method) {
|
|
374
385
|
const value2 = method.bind(this.is);
|
|
375
386
|
METHOD.set(value2, method);
|
|
376
|
-
define(this.is,
|
|
387
|
+
define(this.is, key2, { value: value2, writable: true });
|
|
377
388
|
return value2;
|
|
378
389
|
};
|
|
379
390
|
var bind = bind2;
|
|
380
|
-
let { value } = desc[
|
|
381
|
-
keys.push(
|
|
382
|
-
Object.defineProperty(type.prototype,
|
|
391
|
+
let { value } = desc[key2];
|
|
392
|
+
keys.push(key2);
|
|
393
|
+
Object.defineProperty(type.prototype, key2, {
|
|
383
394
|
set: bind2,
|
|
384
395
|
get() {
|
|
385
|
-
return this.hasOwnProperty(
|
|
396
|
+
return this.hasOwnProperty(key2) ? value : bind2.call(this, value);
|
|
386
397
|
}
|
|
387
398
|
});
|
|
388
399
|
}
|
|
@@ -395,11 +406,21 @@ function uid() {
|
|
|
395
406
|
|
|
396
407
|
// src/context.ts
|
|
397
408
|
var Register = /* @__PURE__ */ new WeakMap();
|
|
409
|
+
var Upstream = /* @__PURE__ */ new WeakMap();
|
|
410
|
+
var Downstream = /* @__PURE__ */ new WeakMap();
|
|
411
|
+
function key(T, upstream) {
|
|
412
|
+
const table = upstream ? Upstream : Downstream;
|
|
413
|
+
let key2 = table.get(T);
|
|
414
|
+
if (!key2) {
|
|
415
|
+
key2 = Symbol(T.name + (upstream ? " request" : ""));
|
|
416
|
+
table.set(T, key2);
|
|
417
|
+
}
|
|
418
|
+
return key2;
|
|
419
|
+
}
|
|
398
420
|
var Context = class _Context {
|
|
399
421
|
constructor(inputs) {
|
|
400
|
-
this.downstream = /* @__PURE__ */ new WeakMap();
|
|
401
|
-
this.upstream = /* @__PURE__ */ new WeakMap();
|
|
402
422
|
this.layer = /* @__PURE__ */ new Map();
|
|
423
|
+
this.cleanup = /* @__PURE__ */ new Set();
|
|
403
424
|
if (inputs)
|
|
404
425
|
this.include(inputs);
|
|
405
426
|
}
|
|
@@ -414,43 +435,40 @@ var Context = class _Context {
|
|
|
414
435
|
else
|
|
415
436
|
Register.set(from, [callback]);
|
|
416
437
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
key = Symbol(T.name + (upstream ? " request" : ""));
|
|
422
|
-
table.set(T, key);
|
|
423
|
-
}
|
|
424
|
-
return key;
|
|
425
|
-
}
|
|
426
|
-
has(model) {
|
|
427
|
-
const key = this.key(model.constructor, true);
|
|
428
|
-
const result = this[key];
|
|
429
|
-
const waiting = Register.get(model);
|
|
430
|
-
if (waiting instanceof Array)
|
|
431
|
-
waiting.forEach((cb) => cb(this));
|
|
432
|
-
Register.set(model, this);
|
|
433
|
-
if (typeof result == "function")
|
|
434
|
-
return result(model);
|
|
435
|
-
}
|
|
436
|
-
get(Type) {
|
|
437
|
-
const result = this[this.key(Type)];
|
|
438
|
+
get(Type, callback) {
|
|
439
|
+
if (callback)
|
|
440
|
+
return this.put(Type, callback);
|
|
441
|
+
const result = this[key(Type)];
|
|
438
442
|
if (result === null)
|
|
439
443
|
throw new Error(`Did find ${Type} in context, but multiple were defined.`);
|
|
440
444
|
return result;
|
|
441
445
|
}
|
|
446
|
+
push(inputs) {
|
|
447
|
+
const next = Object.create(this);
|
|
448
|
+
next.layer = /* @__PURE__ */ new Map();
|
|
449
|
+
next.cleanup = /* @__PURE__ */ new Set();
|
|
450
|
+
if (inputs)
|
|
451
|
+
next.include(inputs);
|
|
452
|
+
return next;
|
|
453
|
+
}
|
|
454
|
+
pop() {
|
|
455
|
+
for (const key2 of Object.getOwnPropertySymbols(this))
|
|
456
|
+
delete this[key2];
|
|
457
|
+
this.cleanup.forEach((cb) => cb());
|
|
458
|
+
this.layer.clear();
|
|
459
|
+
}
|
|
442
460
|
include(inputs, forEach) {
|
|
443
461
|
const init = /* @__PURE__ */ new Map();
|
|
444
462
|
Object.entries(inputs).forEach(([K, V]) => {
|
|
445
463
|
if (!(Model.is(V) || V instanceof Model))
|
|
446
464
|
throw new Error(`Context can only include Model or instance but got ${V}${K && " as " + K}.`);
|
|
447
465
|
});
|
|
448
|
-
for (const
|
|
449
|
-
const input = inputs[
|
|
450
|
-
const exists = this.layer.get(
|
|
466
|
+
for (const key2 in inputs) {
|
|
467
|
+
const input = inputs[key2];
|
|
468
|
+
const exists = this.layer.get(key2);
|
|
451
469
|
if (!exists) {
|
|
452
470
|
const instance = this.add(input);
|
|
453
|
-
this.layer.set(
|
|
471
|
+
this.layer.set(key2, input);
|
|
454
472
|
init.set(instance, true);
|
|
455
473
|
} else if (exists !== input) {
|
|
456
474
|
this.pop();
|
|
@@ -469,118 +487,101 @@ var Context = class _Context {
|
|
|
469
487
|
}
|
|
470
488
|
}
|
|
471
489
|
}
|
|
472
|
-
put(T, I, implicit, writable) {
|
|
473
|
-
do {
|
|
474
|
-
const key = this.key(T, typeof I == "function");
|
|
475
|
-
const value = this.hasOwnProperty(key) ? null : I;
|
|
476
|
-
if (value || this[key] !== I && !implicit)
|
|
477
|
-
Object.defineProperty(this, key, {
|
|
478
|
-
configurable: true,
|
|
479
|
-
writable,
|
|
480
|
-
value
|
|
481
|
-
});
|
|
482
|
-
T = Object.getPrototypeOf(T);
|
|
483
|
-
} while (T !== Model);
|
|
484
|
-
}
|
|
485
490
|
add(input, implicit) {
|
|
486
|
-
let writable = true;
|
|
487
491
|
let T;
|
|
488
492
|
let I;
|
|
489
493
|
if (typeof input == "function") {
|
|
490
494
|
T = input;
|
|
491
495
|
I = new input();
|
|
496
|
+
this.cleanup.add(() => I.set(null));
|
|
492
497
|
} else {
|
|
493
498
|
I = input;
|
|
494
499
|
T = I.constructor;
|
|
495
|
-
writable = false;
|
|
496
500
|
}
|
|
497
|
-
this.has(I);
|
|
498
|
-
this.put(T, I, implicit
|
|
501
|
+
this.has(T, I);
|
|
502
|
+
this.put(T, I, implicit);
|
|
499
503
|
return I;
|
|
500
504
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
505
|
+
has(type, model) {
|
|
506
|
+
do {
|
|
507
|
+
const K = key(type, true);
|
|
508
|
+
const result = this[K];
|
|
509
|
+
if (!result)
|
|
510
|
+
continue;
|
|
511
|
+
const callback = result(model);
|
|
512
|
+
if (callback)
|
|
513
|
+
this.cleanup.add(callback);
|
|
514
|
+
} while ((type = Object.getPrototypeOf(type)) !== Model);
|
|
515
|
+
const waiting = Register.get(model);
|
|
516
|
+
if (waiting instanceof Array)
|
|
517
|
+
waiting.forEach((cb) => cb(this));
|
|
518
|
+
Register.set(model, this);
|
|
507
519
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const
|
|
512
|
-
if (
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
}
|
|
516
|
-
for (const model of items)
|
|
517
|
-
model.set(null);
|
|
518
|
-
this.layer.clear();
|
|
520
|
+
put(T, I, implicit) {
|
|
521
|
+
do {
|
|
522
|
+
const K = key(T, typeof I == "function");
|
|
523
|
+
const value = this.hasOwnProperty(K) ? null : I;
|
|
524
|
+
if (value || this[K] !== I && !implicit)
|
|
525
|
+
Object.defineProperty(this, K, { configurable: true, value });
|
|
526
|
+
} while ((T = Object.getPrototypeOf(T)) !== Model);
|
|
519
527
|
}
|
|
520
528
|
};
|
|
521
529
|
|
|
522
530
|
// src/instruction/use.ts
|
|
523
531
|
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
524
|
-
function use(
|
|
532
|
+
function use(arg1, arg2) {
|
|
525
533
|
const token = Symbol("instruction");
|
|
526
|
-
if (Model.is(
|
|
527
|
-
const type =
|
|
528
|
-
const value = new
|
|
529
|
-
|
|
534
|
+
if (Model.is(arg1)) {
|
|
535
|
+
const type = arg1;
|
|
536
|
+
const value = new type();
|
|
537
|
+
arg1 = (key2, subject) => {
|
|
530
538
|
function set2(next) {
|
|
531
|
-
if (next ? !(next instanceof type) :
|
|
532
|
-
throw new Error(`${subject}.${
|
|
533
|
-
update(subject,
|
|
534
|
-
if (next && typeof
|
|
535
|
-
|
|
539
|
+
if (next ? !(next instanceof type) : arg2 !== false)
|
|
540
|
+
throw new Error(`${subject}.${key2} expected Model of type ${type} but got ${next && next.constructor}.`);
|
|
541
|
+
update(subject, key2, next);
|
|
542
|
+
if (next && typeof arg2 == "function")
|
|
543
|
+
arg2(next);
|
|
536
544
|
return false;
|
|
537
545
|
}
|
|
538
546
|
set2(value);
|
|
539
547
|
return { set: set2, value };
|
|
540
548
|
};
|
|
541
549
|
}
|
|
542
|
-
INSTRUCT.set(token,
|
|
550
|
+
INSTRUCT.set(token, arg1);
|
|
543
551
|
return token;
|
|
544
552
|
}
|
|
545
553
|
Model.on((_, subject) => {
|
|
546
554
|
const state = STATE.get(subject);
|
|
547
555
|
const props = Object.getOwnPropertyDescriptors(subject);
|
|
548
|
-
for (const
|
|
549
|
-
const { value } = props[
|
|
556
|
+
for (const key2 in props) {
|
|
557
|
+
const { value } = props[key2];
|
|
550
558
|
const instruction = INSTRUCT.get(value);
|
|
551
|
-
if (!instruction)
|
|
559
|
+
if (!instruction) {
|
|
560
|
+
if (value instanceof Model && key2 !== "is")
|
|
561
|
+
update(subject, key2, value);
|
|
552
562
|
continue;
|
|
563
|
+
}
|
|
553
564
|
INSTRUCT.delete(value);
|
|
554
|
-
delete subject[
|
|
555
|
-
const output = instruction.call(subject,
|
|
565
|
+
delete subject[key2];
|
|
566
|
+
const output = instruction.call(subject, key2, subject, state);
|
|
556
567
|
if (!output)
|
|
557
568
|
continue;
|
|
558
569
|
const desc = typeof output == "object" ? output : { get: output };
|
|
559
|
-
const { enumerable = true } = desc;
|
|
560
570
|
if ("value" in desc)
|
|
561
|
-
state[
|
|
562
|
-
Object.defineProperty(subject,
|
|
563
|
-
enumerable,
|
|
564
|
-
set(next) {
|
|
565
|
-
let { set: set2 } = desc;
|
|
566
|
-
if (set2 === false)
|
|
567
|
-
throw new Error(`${subject}.${key} is read-only.`);
|
|
568
|
-
if (typeof set2 == "function") {
|
|
569
|
-
const result = set2.call(subject, next, state[key]);
|
|
570
|
-
if (result === false)
|
|
571
|
-
return;
|
|
572
|
-
if (typeof result == "function")
|
|
573
|
-
next = result();
|
|
574
|
-
set2 = false;
|
|
575
|
-
}
|
|
576
|
-
update(subject, key, next, !!set2);
|
|
577
|
-
},
|
|
571
|
+
state[key2] = desc.value;
|
|
572
|
+
Object.defineProperty(subject, key2, {
|
|
573
|
+
enumerable: desc.enumerable !== false,
|
|
578
574
|
get() {
|
|
579
575
|
return watch(
|
|
580
576
|
this,
|
|
581
|
-
|
|
582
|
-
typeof desc.get == "function" ? desc.get(this) : fetch(subject,
|
|
577
|
+
key2,
|
|
578
|
+
typeof desc.get == "function" ? desc.get(this) : fetch(subject, key2, desc.get)
|
|
583
579
|
);
|
|
580
|
+
},
|
|
581
|
+
set(next) {
|
|
582
|
+
if (desc.set === false)
|
|
583
|
+
throw new Error(`${subject}.${key2} is read-only.`);
|
|
584
|
+
update(subject, key2, next, desc.set);
|
|
584
585
|
}
|
|
585
586
|
});
|
|
586
587
|
}
|
|
@@ -590,10 +591,10 @@ Model.on((_, subject) => {
|
|
|
590
591
|
// src/instruction/get.ts
|
|
591
592
|
var STALE = /* @__PURE__ */ new WeakSet();
|
|
592
593
|
function get(arg0, arg1) {
|
|
593
|
-
return use((
|
|
594
|
+
return use((key2, subject, state) => {
|
|
594
595
|
let from = subject;
|
|
595
596
|
if (typeof arg0 == "symbol")
|
|
596
|
-
throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${
|
|
597
|
+
throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key2}. This is not allowed.`);
|
|
597
598
|
let source = (resolve) => resolve(from);
|
|
598
599
|
if (arg0 instanceof Model) {
|
|
599
600
|
from = arg0;
|
|
@@ -623,26 +624,26 @@ function get(arg0, arg1) {
|
|
|
623
624
|
let connect2 = function(model) {
|
|
624
625
|
reset = effect(model, (current) => {
|
|
625
626
|
proxy = current;
|
|
626
|
-
if (!(
|
|
627
|
+
if (!(key2 in state) || STALE.delete(compute2))
|
|
627
628
|
compute2(!reset);
|
|
628
629
|
return (didUpdate) => {
|
|
629
630
|
if (didUpdate) {
|
|
630
631
|
STALE.add(compute2);
|
|
631
|
-
push(subject,
|
|
632
|
+
push(subject, key2, true);
|
|
632
633
|
}
|
|
633
634
|
};
|
|
634
635
|
});
|
|
635
636
|
}, compute2 = function(initial) {
|
|
636
637
|
let next;
|
|
637
638
|
try {
|
|
638
|
-
next = getter.call(proxy, proxy,
|
|
639
|
+
next = getter.call(proxy, proxy, key2);
|
|
639
640
|
} catch (err) {
|
|
640
|
-
console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${
|
|
641
|
+
console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key2}.`);
|
|
641
642
|
if (initial)
|
|
642
643
|
throw err;
|
|
643
644
|
console.error(err);
|
|
644
645
|
}
|
|
645
|
-
update(subject,
|
|
646
|
+
update(subject, key2, next, !isAsync);
|
|
646
647
|
};
|
|
647
648
|
var connect = connect2, compute = compute2;
|
|
648
649
|
const getter = arg1;
|
|
@@ -656,10 +657,10 @@ function get(arg0, arg1) {
|
|
|
656
657
|
}
|
|
657
658
|
if (STALE.delete(compute2))
|
|
658
659
|
compute2();
|
|
659
|
-
return fetch(subject,
|
|
660
|
+
return fetch(subject, key2, !proxy);
|
|
660
661
|
};
|
|
661
662
|
} else
|
|
662
|
-
source((got) => subject.set(
|
|
663
|
+
source((got) => subject.set(key2, got));
|
|
663
664
|
return { get: arg1 };
|
|
664
665
|
});
|
|
665
666
|
}
|
|
@@ -667,35 +668,35 @@ function get(arg0, arg1) {
|
|
|
667
668
|
// src/instruction/ref.ts
|
|
668
669
|
var define2 = Object.defineProperty;
|
|
669
670
|
function ref(arg, arg2) {
|
|
670
|
-
return use((
|
|
671
|
+
return use((key2, subject, state) => {
|
|
671
672
|
let value = {};
|
|
672
673
|
if (arg === subject)
|
|
673
674
|
subject.get(() => {
|
|
674
|
-
for (const
|
|
675
|
+
for (const key3 in state)
|
|
675
676
|
if (typeof arg2 == "function")
|
|
676
|
-
define2(value,
|
|
677
|
+
define2(value, key3, {
|
|
677
678
|
configurable: true,
|
|
678
679
|
get() {
|
|
679
|
-
const out = arg2(
|
|
680
|
-
define2(value,
|
|
680
|
+
const out = arg2(key3);
|
|
681
|
+
define2(value, key3, { value: out });
|
|
681
682
|
return out;
|
|
682
683
|
}
|
|
683
684
|
});
|
|
684
685
|
else {
|
|
685
|
-
const get2 = () => state[
|
|
686
|
-
const set2 = (value2) => subject.set(
|
|
686
|
+
const get2 = () => state[key3];
|
|
687
|
+
const set2 = (value2) => subject.set(key3, value2);
|
|
687
688
|
define2(set2, "current", { get: get2, set: set2 });
|
|
688
689
|
define2(set2, "get", { value: get2 });
|
|
689
|
-
define2(value,
|
|
690
|
+
define2(value, key3, { value: set2 });
|
|
690
691
|
}
|
|
691
692
|
});
|
|
692
693
|
else if (typeof arg == "object")
|
|
693
694
|
throw new Error("ref instruction does not support object which is not 'this'");
|
|
694
695
|
else {
|
|
695
696
|
let unSet;
|
|
696
|
-
const get2 = () => state[
|
|
697
|
+
const get2 = () => state[key2];
|
|
697
698
|
const set2 = (value2) => {
|
|
698
|
-
if (!subject.set(
|
|
699
|
+
if (!subject.set(key2, value2) || !arg)
|
|
699
700
|
return;
|
|
700
701
|
if (unSet)
|
|
701
702
|
unSet = void unSet(value2);
|
|
@@ -705,44 +706,44 @@ function ref(arg, arg2) {
|
|
|
705
706
|
unSet = out;
|
|
706
707
|
}
|
|
707
708
|
};
|
|
708
|
-
state[
|
|
709
|
+
state[key2] = null;
|
|
709
710
|
value = Object.defineProperties(set2, {
|
|
710
711
|
current: { get: get2, set: set2 },
|
|
711
712
|
get: { value: get2 }
|
|
712
713
|
});
|
|
713
714
|
}
|
|
714
|
-
define2(subject,
|
|
715
|
+
define2(subject, key2, { value });
|
|
715
716
|
});
|
|
716
717
|
}
|
|
717
718
|
|
|
718
719
|
// src/instruction/set.ts
|
|
719
720
|
function set(value, argument) {
|
|
720
|
-
return use((
|
|
721
|
+
return use((key2, subject) => {
|
|
721
722
|
const output = {};
|
|
722
723
|
if (typeof value == "function" || value instanceof Promise) {
|
|
723
724
|
let init2 = function() {
|
|
724
725
|
if (typeof value == "function")
|
|
725
726
|
try {
|
|
726
|
-
value = attempt(value.bind(subject,
|
|
727
|
+
value = attempt(value.bind(subject, key2));
|
|
727
728
|
} catch (err) {
|
|
728
|
-
console.warn(`Generating initial value for ${subject}.${
|
|
729
|
+
console.warn(`Generating initial value for ${subject}.${key2} failed.`);
|
|
729
730
|
throw err;
|
|
730
731
|
}
|
|
731
|
-
output.get =
|
|
732
|
+
output.get = argument === true;
|
|
732
733
|
if (value instanceof Promise) {
|
|
733
734
|
value.then((value2) => {
|
|
734
|
-
subject.set(
|
|
735
|
+
subject.set(key2, value2);
|
|
735
736
|
return value2;
|
|
736
737
|
}).catch((err) => {
|
|
737
|
-
subject.set(
|
|
738
|
+
subject.set(key2);
|
|
738
739
|
output.get = () => {
|
|
739
740
|
throw err;
|
|
740
741
|
};
|
|
741
742
|
});
|
|
742
743
|
} else
|
|
743
|
-
subject.set(
|
|
744
|
+
subject.set(key2, value);
|
|
744
745
|
if (0 in arguments)
|
|
745
|
-
return subject[
|
|
746
|
+
return subject[key2];
|
|
746
747
|
};
|
|
747
748
|
var init = init2;
|
|
748
749
|
if (argument)
|
|
@@ -765,7 +766,7 @@ function set(value, argument) {
|
|
|
765
766
|
} else
|
|
766
767
|
output.set = (value2) => {
|
|
767
768
|
output.get = void 0;
|
|
768
|
-
subject.set(
|
|
769
|
+
subject.set(key2, value2);
|
|
769
770
|
};
|
|
770
771
|
return output;
|
|
771
772
|
});
|
|
@@ -789,47 +790,77 @@ function attempt(fn) {
|
|
|
789
790
|
}
|
|
790
791
|
|
|
791
792
|
// src/instruction/has.ts
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
793
|
+
var APPLY = /* @__PURE__ */ new WeakMap();
|
|
794
|
+
function has(arg1, arg2) {
|
|
795
|
+
return use((key2, subject) => {
|
|
796
|
+
const applied = /* @__PURE__ */ new Set();
|
|
797
|
+
const update2 = () => {
|
|
798
|
+
subject.set(key2, Object.freeze(Array.from(applied)));
|
|
799
|
+
};
|
|
800
|
+
if (!Model.is(arg1)) {
|
|
801
|
+
if (APPLY.has(subject))
|
|
802
|
+
throw new Error(`'has' callback can only be used once per model.`);
|
|
803
|
+
APPLY.set(subject, (recipient) => {
|
|
804
|
+
let remove;
|
|
805
|
+
if (arg1) {
|
|
806
|
+
remove = arg1(recipient, subject);
|
|
807
|
+
if (remove === false)
|
|
808
|
+
return false;
|
|
809
|
+
}
|
|
810
|
+
applied.add(recipient);
|
|
811
|
+
update2();
|
|
812
|
+
return () => {
|
|
813
|
+
applied.delete(recipient);
|
|
814
|
+
update2();
|
|
815
|
+
if (typeof remove == "function")
|
|
816
|
+
remove();
|
|
801
817
|
};
|
|
802
|
-
model.get(null, remove);
|
|
803
|
-
return remove;
|
|
804
818
|
});
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
819
|
+
} else
|
|
820
|
+
Context.get(subject, (ctx) => ctx.get(arg1, (got) => {
|
|
821
|
+
let remove;
|
|
822
|
+
let disconnect;
|
|
823
|
+
if (applied.has(got))
|
|
824
|
+
return;
|
|
825
|
+
const callback = APPLY.get(got);
|
|
826
|
+
if (callback) {
|
|
827
|
+
const after = callback(subject);
|
|
828
|
+
if (after === false)
|
|
829
|
+
return;
|
|
830
|
+
if (typeof after == "function")
|
|
831
|
+
disconnect = after;
|
|
832
|
+
}
|
|
833
|
+
if (typeof arg2 == "function") {
|
|
834
|
+
const done2 = arg2(got, subject);
|
|
835
|
+
if (done2 === false)
|
|
836
|
+
return false;
|
|
837
|
+
remove = () => {
|
|
838
|
+
if (typeof done2 == "function")
|
|
839
|
+
done2();
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
applied.add(got);
|
|
843
|
+
update2();
|
|
844
|
+
const done = () => {
|
|
845
|
+
reset();
|
|
846
|
+
applied.delete(got);
|
|
847
|
+
update2();
|
|
848
|
+
if (disconnect)
|
|
849
|
+
disconnect();
|
|
850
|
+
if (typeof remove == "function")
|
|
851
|
+
remove();
|
|
852
|
+
};
|
|
853
|
+
const reset = got.get(null, done);
|
|
854
|
+
return done;
|
|
855
|
+
}));
|
|
856
|
+
return { value: [] };
|
|
827
857
|
});
|
|
828
858
|
}
|
|
829
859
|
export {
|
|
830
860
|
Context,
|
|
831
861
|
Model,
|
|
832
862
|
Model as default,
|
|
863
|
+
effect,
|
|
833
864
|
get,
|
|
834
865
|
has,
|
|
835
866
|
ref,
|