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