@expressive/mvc 0.45.0 → 0.47.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 +5 -17
- package/dist/index.js +103 -98
- package/dist/index.mjs +103 -97
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ declare namespace Model {
|
|
|
15
15
|
type Field<T> = Exclude<keyof T, keyof Model>;
|
|
16
16
|
/** Any valid key for controller, including but not limited to Field<T>. */
|
|
17
17
|
type Event<T> = Field<T> | (string & {}) | number | symbol;
|
|
18
|
-
/** Object overlay which may be used to override values and methods
|
|
18
|
+
/** Object overlay which may be used to override values and methods on a model. */
|
|
19
19
|
type Assign<T> = {
|
|
20
20
|
[K in Exclude<keyof T, keyof Model>]?: T[K] extends (...args: infer A) => infer R ? (this: T, ...args: A) => R : T[K];
|
|
21
21
|
} & Record<string, unknown>;
|
|
@@ -201,8 +201,6 @@ declare class Model {
|
|
|
201
201
|
static at<T extends Model>(this: Model.Type<T>, from: Model, cb: (got: T | undefined) => void): void;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
declare function add<T = any>(instruction: Model.Instruction): T;
|
|
205
|
-
|
|
206
204
|
declare namespace get {
|
|
207
205
|
type Function<T, S = any> = (on: S, key: string) => T;
|
|
208
206
|
type Factory<T, S = any> = (this: S, key: string, thisArg: S) => T;
|
|
@@ -346,19 +344,9 @@ declare function set<T>(factory: set.Factory<T> | Promise<T>, required?: boolean
|
|
|
346
344
|
*/
|
|
347
345
|
declare function set<T>(value: T | undefined, onUpdate: set.Callback<T>): T;
|
|
348
346
|
|
|
349
|
-
|
|
350
|
-
declare function use<T extends Model>(): T | undefined;
|
|
351
|
-
/** Create a new child instance of model. */
|
|
347
|
+
declare function use<T = any>(instruction: Model.Instruction): T;
|
|
348
|
+
declare function use<T extends Model>(Type: Model.Type<T>, required: false): T | undefined;
|
|
352
349
|
declare function use<T extends Model>(Type: Model.Type<T>, ready?: (i: T) => void): T;
|
|
353
|
-
/**
|
|
354
|
-
* Use existing model as a child of model assigned to.
|
|
355
|
-
*
|
|
356
|
-
* Note: If `peer` is not already initialized before parent is
|
|
357
|
-
* (created with `new` as opposed to create method), that model will
|
|
358
|
-
* attach this via `parent()` instruction. It will not, however, if
|
|
359
|
-
* already active.
|
|
360
|
-
**/
|
|
361
|
-
declare function use<T extends Model>(model: T, ready?: (i: T) => void): T;
|
|
362
350
|
|
|
363
351
|
declare namespace has {
|
|
364
352
|
type Callback<T = any> = (model: T) => void | boolean | (() => void);
|
|
@@ -380,7 +368,7 @@ declare class Context {
|
|
|
380
368
|
key(T: Model.Type, upstream?: boolean): keyof this;
|
|
381
369
|
has(model: Model): (() => void) | undefined;
|
|
382
370
|
get<T extends Model>(Type: Model.Type<T>): T | undefined;
|
|
383
|
-
include(inputs: Context.Input
|
|
371
|
+
include(inputs: Context.Input, forEach?: (added: Model, explicit: boolean) => void): void;
|
|
384
372
|
put<T extends Model>(T: Model.Type<T>, I: T | ((model: T) => void), implicit?: boolean, writable?: boolean): void;
|
|
385
373
|
add<T extends Model>(input: T | Model.Type<T>, implicit?: boolean): T;
|
|
386
374
|
push(inputs?: Context.Input): this;
|
|
@@ -404,4 +392,4 @@ declare global {
|
|
|
404
392
|
}
|
|
405
393
|
}
|
|
406
394
|
|
|
407
|
-
export { Context, Model,
|
|
395
|
+
export { Context, Model, Model as default, get, has, ref, set, use };
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,6 @@ var src_exports = {};
|
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
Context: () => Context,
|
|
24
24
|
Model: () => Model,
|
|
25
|
-
add: () => add,
|
|
26
25
|
default: () => Model,
|
|
27
26
|
get: () => get,
|
|
28
27
|
has: () => has,
|
|
@@ -66,13 +65,16 @@ function watch(from, key, value) {
|
|
|
66
65
|
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
67
66
|
function event(source, key) {
|
|
68
67
|
const subs = LISTENER.get(source);
|
|
68
|
+
const ready = !subs.has(onReady);
|
|
69
|
+
if (key === true && ready)
|
|
70
|
+
return;
|
|
69
71
|
let pending = PENDING.get(source);
|
|
70
72
|
if (pending) {
|
|
71
73
|
pending.add(key);
|
|
72
74
|
return;
|
|
73
75
|
}
|
|
74
76
|
PENDING.set(source, pending = new Set(
|
|
75
|
-
key !== true &&
|
|
77
|
+
key !== true && ready ? [key] : [true, key]
|
|
76
78
|
));
|
|
77
79
|
pending.forEach((key2) => {
|
|
78
80
|
pending.delete(key2);
|
|
@@ -194,7 +196,7 @@ var Model = class _Model {
|
|
|
194
196
|
for (const key in this) {
|
|
195
197
|
const desc = Object.getOwnPropertyDescriptor(this, key);
|
|
196
198
|
if ("value" in desc) {
|
|
197
|
-
|
|
199
|
+
update(this, key, desc.value, true);
|
|
198
200
|
define(this, key, {
|
|
199
201
|
configurable: false,
|
|
200
202
|
set: (x) => update(this, key, x),
|
|
@@ -204,6 +206,8 @@ var Model = class _Model {
|
|
|
204
206
|
});
|
|
205
207
|
}
|
|
206
208
|
}
|
|
209
|
+
if (!PARENT.has(this))
|
|
210
|
+
PARENT.set(this, null);
|
|
207
211
|
addListener(this, () => {
|
|
208
212
|
if (!done)
|
|
209
213
|
throw new Error(`Tried to destroy ${this} but not fully initialized.`);
|
|
@@ -266,11 +270,12 @@ var Model = class _Model {
|
|
|
266
270
|
return event(this, null);
|
|
267
271
|
if (typeof arg1 == "object")
|
|
268
272
|
assign(self, arg1);
|
|
269
|
-
else if (arg1
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
else if (arg1 == void 0)
|
|
274
|
+
event(this, true);
|
|
275
|
+
else if (1 in arguments)
|
|
276
|
+
update(self, arg1, arg2, arg3);
|
|
277
|
+
else
|
|
278
|
+
push(self, arg1);
|
|
274
279
|
if (PENDING2.has(self))
|
|
275
280
|
return {
|
|
276
281
|
then: (res) => new Promise((res2) => {
|
|
@@ -364,6 +369,10 @@ function update(subject, key, value, silent) {
|
|
|
364
369
|
const previous = state[key];
|
|
365
370
|
if (value === previous)
|
|
366
371
|
return true;
|
|
372
|
+
if (value instanceof Model && !PARENT.has(value)) {
|
|
373
|
+
PARENT.set(value, subject);
|
|
374
|
+
event(value, true);
|
|
375
|
+
}
|
|
367
376
|
state[key] = value;
|
|
368
377
|
if (silent !== true)
|
|
369
378
|
push(subject, key);
|
|
@@ -420,26 +429,42 @@ function uid() {
|
|
|
420
429
|
return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
|
|
421
430
|
}
|
|
422
431
|
|
|
423
|
-
// src/instruction/
|
|
432
|
+
// src/instruction/use.ts
|
|
424
433
|
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
425
|
-
function
|
|
434
|
+
function use(model, argument) {
|
|
426
435
|
const token = Symbol("instruction");
|
|
427
|
-
|
|
436
|
+
if (Model.is(model)) {
|
|
437
|
+
const type = model;
|
|
438
|
+
const value = new model();
|
|
439
|
+
model = (key, subject) => {
|
|
440
|
+
function set2(next) {
|
|
441
|
+
if (next ? !(next instanceof type) : argument !== false)
|
|
442
|
+
throw new Error(`${subject}.${key} expected Model of type ${type} but got ${next && next.constructor}.`);
|
|
443
|
+
update(subject, key, next);
|
|
444
|
+
if (next && typeof argument == "function")
|
|
445
|
+
argument(next);
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
set2(value);
|
|
449
|
+
return { set: set2, value };
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
INSTRUCT.set(token, model);
|
|
428
453
|
return token;
|
|
429
454
|
}
|
|
430
455
|
Model.on((_, subject) => {
|
|
431
456
|
const state = STATE.get(subject);
|
|
432
|
-
Object.
|
|
433
|
-
|
|
434
|
-
|
|
457
|
+
const props = Object.getOwnPropertyDescriptors(subject);
|
|
458
|
+
for (const key in props) {
|
|
459
|
+
const { value } = props[key];
|
|
435
460
|
const instruction = INSTRUCT.get(value);
|
|
436
461
|
if (!instruction)
|
|
437
|
-
|
|
462
|
+
continue;
|
|
438
463
|
INSTRUCT.delete(value);
|
|
439
464
|
delete subject[key];
|
|
440
465
|
const output = instruction.call(subject, key, subject, state);
|
|
441
466
|
if (!output)
|
|
442
|
-
|
|
467
|
+
continue;
|
|
443
468
|
const desc = typeof output == "object" ? output : { get: output };
|
|
444
469
|
const { enumerable = true } = desc;
|
|
445
470
|
if ("value" in desc)
|
|
@@ -468,20 +493,21 @@ Model.on((_, subject) => {
|
|
|
468
493
|
);
|
|
469
494
|
}
|
|
470
495
|
});
|
|
471
|
-
}
|
|
496
|
+
}
|
|
472
497
|
return null;
|
|
473
498
|
});
|
|
474
499
|
|
|
475
500
|
// src/instruction/get.ts
|
|
501
|
+
var STALE = /* @__PURE__ */ new WeakSet();
|
|
476
502
|
function get(arg0, arg1) {
|
|
477
|
-
return
|
|
503
|
+
return use((key, subject) => {
|
|
478
504
|
let from = subject;
|
|
479
505
|
if (typeof arg0 == "symbol")
|
|
480
506
|
throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key}. This is not allowed.`);
|
|
481
507
|
let source = (resolve) => resolve(from);
|
|
482
|
-
if (arg0 instanceof Model)
|
|
508
|
+
if (arg0 instanceof Model) {
|
|
483
509
|
from = arg0;
|
|
484
|
-
else if (Model
|
|
510
|
+
} else if (arg0.prototype instanceof Model) {
|
|
485
511
|
const hasParent = PARENT.get(from);
|
|
486
512
|
if (!hasParent) {
|
|
487
513
|
if (arg1 === true)
|
|
@@ -498,63 +524,61 @@ function get(arg0, arg1) {
|
|
|
498
524
|
from = hasParent;
|
|
499
525
|
else
|
|
500
526
|
throw new Error(`New ${from} created as child of ${hasParent}, but must be instanceof ${arg0}.`);
|
|
501
|
-
} else
|
|
527
|
+
} else {
|
|
502
528
|
const fn = METHOD.get(arg0) || arg0;
|
|
503
529
|
arg1 = (p, k) => fn.call(p, k, p);
|
|
504
530
|
}
|
|
505
|
-
if (typeof arg1 == "function")
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
531
|
+
if (typeof arg1 == "function") {
|
|
532
|
+
let connect2 = function(model) {
|
|
533
|
+
reset = effect(model, (current) => {
|
|
534
|
+
proxy = current;
|
|
535
|
+
if (!reset)
|
|
536
|
+
compute2(true);
|
|
537
|
+
else if (STALE.delete(compute2))
|
|
538
|
+
compute2();
|
|
539
|
+
return (didUpdate) => {
|
|
540
|
+
if (didUpdate) {
|
|
541
|
+
STALE.add(compute2);
|
|
542
|
+
push(subject, key, true);
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
});
|
|
546
|
+
}, compute2 = function(initial) {
|
|
547
|
+
let next;
|
|
548
|
+
try {
|
|
549
|
+
next = getter.call(proxy, proxy, key);
|
|
550
|
+
} catch (err) {
|
|
551
|
+
console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key}.`);
|
|
552
|
+
if (initial)
|
|
553
|
+
throw err;
|
|
554
|
+
console.error(err);
|
|
527
555
|
}
|
|
556
|
+
update(subject, key, next, !isAsync);
|
|
528
557
|
};
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
}
|
|
548
|
-
if (STALE.delete(compute2))
|
|
549
|
-
compute2();
|
|
550
|
-
return fetch(subject, key, !proxy);
|
|
551
|
-
};
|
|
558
|
+
var connect = connect2, compute = compute2;
|
|
559
|
+
const getter = arg1;
|
|
560
|
+
let reset;
|
|
561
|
+
let isAsync;
|
|
562
|
+
let proxy;
|
|
563
|
+
return () => {
|
|
564
|
+
if (!proxy) {
|
|
565
|
+
source(connect2);
|
|
566
|
+
isAsync = true;
|
|
567
|
+
}
|
|
568
|
+
if (STALE.delete(compute2))
|
|
569
|
+
compute2();
|
|
570
|
+
return fetch(subject, key, !proxy);
|
|
571
|
+
};
|
|
572
|
+
} else
|
|
573
|
+
source((got) => subject.set(key, got));
|
|
574
|
+
return { get: arg1 };
|
|
575
|
+
});
|
|
552
576
|
}
|
|
553
577
|
|
|
554
578
|
// src/instruction/ref.ts
|
|
555
579
|
var define2 = Object.defineProperty;
|
|
556
580
|
function ref(arg, arg2) {
|
|
557
|
-
return
|
|
581
|
+
return use((key, subject, state) => {
|
|
558
582
|
let value = {};
|
|
559
583
|
if (arg === subject)
|
|
560
584
|
subject.get(() => {
|
|
@@ -604,7 +628,7 @@ function ref(arg, arg2) {
|
|
|
604
628
|
|
|
605
629
|
// src/instruction/set.ts
|
|
606
630
|
function set(value, argument) {
|
|
607
|
-
return
|
|
631
|
+
return use((key, subject) => {
|
|
608
632
|
const output = {};
|
|
609
633
|
if (typeof value == "function" || value instanceof Promise) {
|
|
610
634
|
let init2 = function() {
|
|
@@ -660,11 +684,11 @@ function set(value, argument) {
|
|
|
660
684
|
function attempt(fn) {
|
|
661
685
|
function retry(err) {
|
|
662
686
|
if (err instanceof Promise)
|
|
663
|
-
return err.then(
|
|
687
|
+
return err.then(compute);
|
|
664
688
|
else
|
|
665
689
|
throw err;
|
|
666
690
|
}
|
|
667
|
-
function
|
|
691
|
+
function compute() {
|
|
668
692
|
try {
|
|
669
693
|
const output = fn();
|
|
670
694
|
return output instanceof Promise ? output.catch(retry) : output;
|
|
@@ -672,27 +696,7 @@ function attempt(fn) {
|
|
|
672
696
|
return retry(err);
|
|
673
697
|
}
|
|
674
698
|
}
|
|
675
|
-
return
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
// src/instruction/use.ts
|
|
679
|
-
function use(value, argument) {
|
|
680
|
-
return add((property, subject) => {
|
|
681
|
-
if (typeof value === "function")
|
|
682
|
-
value = new value();
|
|
683
|
-
function set2(next) {
|
|
684
|
-
if (value instanceof Model && !(next instanceof value.constructor))
|
|
685
|
-
throw new Error(`${subject}.${property} expected Model of type ${value.constructor} but got ${next}.`);
|
|
686
|
-
if (next instanceof Model) {
|
|
687
|
-
PARENT.set(next, subject);
|
|
688
|
-
event(next, true);
|
|
689
|
-
}
|
|
690
|
-
if (typeof argument == "function")
|
|
691
|
-
argument(next);
|
|
692
|
-
}
|
|
693
|
-
set2(value);
|
|
694
|
-
return { set: set2, value };
|
|
695
|
-
});
|
|
699
|
+
return compute();
|
|
696
700
|
}
|
|
697
701
|
|
|
698
702
|
// src/context.ts
|
|
@@ -732,7 +736,7 @@ var Context = class {
|
|
|
732
736
|
throw new Error(`Did find ${Type} in context, but multiple were defined.`);
|
|
733
737
|
return result;
|
|
734
738
|
}
|
|
735
|
-
include(inputs) {
|
|
739
|
+
include(inputs, forEach) {
|
|
736
740
|
const init = /* @__PURE__ */ new Map();
|
|
737
741
|
if (typeof inputs == "function" || inputs instanceof Model)
|
|
738
742
|
inputs = { [0]: inputs };
|
|
@@ -752,10 +756,13 @@ var Context = class {
|
|
|
752
756
|
} else if (exists !== input) {
|
|
753
757
|
this.pop();
|
|
754
758
|
this.id = uid();
|
|
755
|
-
|
|
759
|
+
this.include(inputs);
|
|
756
760
|
}
|
|
757
761
|
}
|
|
758
|
-
for (const [model] of init) {
|
|
762
|
+
for (const [model, explicit] of init) {
|
|
763
|
+
if (forEach)
|
|
764
|
+
forEach(model, explicit);
|
|
765
|
+
model.set();
|
|
759
766
|
this.has(model);
|
|
760
767
|
const expects = Expects.get(model);
|
|
761
768
|
if (expects)
|
|
@@ -767,7 +774,6 @@ var Context = class {
|
|
|
767
774
|
init.set(value, false);
|
|
768
775
|
}
|
|
769
776
|
}
|
|
770
|
-
return init;
|
|
771
777
|
}
|
|
772
778
|
put(T, I, implicit, writable) {
|
|
773
779
|
do {
|
|
@@ -788,7 +794,7 @@ var Context = class {
|
|
|
788
794
|
let I;
|
|
789
795
|
if (typeof input == "function") {
|
|
790
796
|
T = input;
|
|
791
|
-
I = input
|
|
797
|
+
I = new input();
|
|
792
798
|
} else {
|
|
793
799
|
I = input;
|
|
794
800
|
T = I.constructor;
|
|
@@ -823,7 +829,7 @@ function reject(argument) {
|
|
|
823
829
|
|
|
824
830
|
// src/instruction/has.ts
|
|
825
831
|
function has(type, argument) {
|
|
826
|
-
return
|
|
832
|
+
return use((key, subject, state) => {
|
|
827
833
|
if (typeof argument == "boolean") {
|
|
828
834
|
Context.request(type, subject, (model) => {
|
|
829
835
|
subject.set(key, model);
|
|
@@ -865,7 +871,6 @@ function has(type, argument) {
|
|
|
865
871
|
0 && (module.exports = {
|
|
866
872
|
Context,
|
|
867
873
|
Model,
|
|
868
|
-
add,
|
|
869
874
|
get,
|
|
870
875
|
has,
|
|
871
876
|
ref,
|
package/dist/index.mjs
CHANGED
|
@@ -32,13 +32,16 @@ function watch(from, key, value) {
|
|
|
32
32
|
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
33
33
|
function event(source, key) {
|
|
34
34
|
const subs = LISTENER.get(source);
|
|
35
|
+
const ready = !subs.has(onReady);
|
|
36
|
+
if (key === true && ready)
|
|
37
|
+
return;
|
|
35
38
|
let pending = PENDING.get(source);
|
|
36
39
|
if (pending) {
|
|
37
40
|
pending.add(key);
|
|
38
41
|
return;
|
|
39
42
|
}
|
|
40
43
|
PENDING.set(source, pending = new Set(
|
|
41
|
-
key !== true &&
|
|
44
|
+
key !== true && ready ? [key] : [true, key]
|
|
42
45
|
));
|
|
43
46
|
pending.forEach((key2) => {
|
|
44
47
|
pending.delete(key2);
|
|
@@ -160,7 +163,7 @@ var Model = class _Model {
|
|
|
160
163
|
for (const key in this) {
|
|
161
164
|
const desc = Object.getOwnPropertyDescriptor(this, key);
|
|
162
165
|
if ("value" in desc) {
|
|
163
|
-
|
|
166
|
+
update(this, key, desc.value, true);
|
|
164
167
|
define(this, key, {
|
|
165
168
|
configurable: false,
|
|
166
169
|
set: (x) => update(this, key, x),
|
|
@@ -170,6 +173,8 @@ var Model = class _Model {
|
|
|
170
173
|
});
|
|
171
174
|
}
|
|
172
175
|
}
|
|
176
|
+
if (!PARENT.has(this))
|
|
177
|
+
PARENT.set(this, null);
|
|
173
178
|
addListener(this, () => {
|
|
174
179
|
if (!done)
|
|
175
180
|
throw new Error(`Tried to destroy ${this} but not fully initialized.`);
|
|
@@ -232,11 +237,12 @@ var Model = class _Model {
|
|
|
232
237
|
return event(this, null);
|
|
233
238
|
if (typeof arg1 == "object")
|
|
234
239
|
assign(self, arg1);
|
|
235
|
-
else if (arg1
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
+
else if (arg1 == void 0)
|
|
241
|
+
event(this, true);
|
|
242
|
+
else if (1 in arguments)
|
|
243
|
+
update(self, arg1, arg2, arg3);
|
|
244
|
+
else
|
|
245
|
+
push(self, arg1);
|
|
240
246
|
if (PENDING2.has(self))
|
|
241
247
|
return {
|
|
242
248
|
then: (res) => new Promise((res2) => {
|
|
@@ -330,6 +336,10 @@ function update(subject, key, value, silent) {
|
|
|
330
336
|
const previous = state[key];
|
|
331
337
|
if (value === previous)
|
|
332
338
|
return true;
|
|
339
|
+
if (value instanceof Model && !PARENT.has(value)) {
|
|
340
|
+
PARENT.set(value, subject);
|
|
341
|
+
event(value, true);
|
|
342
|
+
}
|
|
333
343
|
state[key] = value;
|
|
334
344
|
if (silent !== true)
|
|
335
345
|
push(subject, key);
|
|
@@ -386,26 +396,42 @@ function uid() {
|
|
|
386
396
|
return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
|
|
387
397
|
}
|
|
388
398
|
|
|
389
|
-
// src/instruction/
|
|
399
|
+
// src/instruction/use.ts
|
|
390
400
|
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
391
|
-
function
|
|
401
|
+
function use(model, argument) {
|
|
392
402
|
const token = Symbol("instruction");
|
|
393
|
-
|
|
403
|
+
if (Model.is(model)) {
|
|
404
|
+
const type = model;
|
|
405
|
+
const value = new model();
|
|
406
|
+
model = (key, subject) => {
|
|
407
|
+
function set2(next) {
|
|
408
|
+
if (next ? !(next instanceof type) : argument !== false)
|
|
409
|
+
throw new Error(`${subject}.${key} expected Model of type ${type} but got ${next && next.constructor}.`);
|
|
410
|
+
update(subject, key, next);
|
|
411
|
+
if (next && typeof argument == "function")
|
|
412
|
+
argument(next);
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
set2(value);
|
|
416
|
+
return { set: set2, value };
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
INSTRUCT.set(token, model);
|
|
394
420
|
return token;
|
|
395
421
|
}
|
|
396
422
|
Model.on((_, subject) => {
|
|
397
423
|
const state = STATE.get(subject);
|
|
398
|
-
Object.
|
|
399
|
-
|
|
400
|
-
|
|
424
|
+
const props = Object.getOwnPropertyDescriptors(subject);
|
|
425
|
+
for (const key in props) {
|
|
426
|
+
const { value } = props[key];
|
|
401
427
|
const instruction = INSTRUCT.get(value);
|
|
402
428
|
if (!instruction)
|
|
403
|
-
|
|
429
|
+
continue;
|
|
404
430
|
INSTRUCT.delete(value);
|
|
405
431
|
delete subject[key];
|
|
406
432
|
const output = instruction.call(subject, key, subject, state);
|
|
407
433
|
if (!output)
|
|
408
|
-
|
|
434
|
+
continue;
|
|
409
435
|
const desc = typeof output == "object" ? output : { get: output };
|
|
410
436
|
const { enumerable = true } = desc;
|
|
411
437
|
if ("value" in desc)
|
|
@@ -434,20 +460,21 @@ Model.on((_, subject) => {
|
|
|
434
460
|
);
|
|
435
461
|
}
|
|
436
462
|
});
|
|
437
|
-
}
|
|
463
|
+
}
|
|
438
464
|
return null;
|
|
439
465
|
});
|
|
440
466
|
|
|
441
467
|
// src/instruction/get.ts
|
|
468
|
+
var STALE = /* @__PURE__ */ new WeakSet();
|
|
442
469
|
function get(arg0, arg1) {
|
|
443
|
-
return
|
|
470
|
+
return use((key, subject) => {
|
|
444
471
|
let from = subject;
|
|
445
472
|
if (typeof arg0 == "symbol")
|
|
446
473
|
throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key}. This is not allowed.`);
|
|
447
474
|
let source = (resolve) => resolve(from);
|
|
448
|
-
if (arg0 instanceof Model)
|
|
475
|
+
if (arg0 instanceof Model) {
|
|
449
476
|
from = arg0;
|
|
450
|
-
else if (Model
|
|
477
|
+
} else if (arg0.prototype instanceof Model) {
|
|
451
478
|
const hasParent = PARENT.get(from);
|
|
452
479
|
if (!hasParent) {
|
|
453
480
|
if (arg1 === true)
|
|
@@ -464,63 +491,61 @@ function get(arg0, arg1) {
|
|
|
464
491
|
from = hasParent;
|
|
465
492
|
else
|
|
466
493
|
throw new Error(`New ${from} created as child of ${hasParent}, but must be instanceof ${arg0}.`);
|
|
467
|
-
} else
|
|
494
|
+
} else {
|
|
468
495
|
const fn = METHOD.get(arg0) || arg0;
|
|
469
496
|
arg1 = (p, k) => fn.call(p, k, p);
|
|
470
497
|
}
|
|
471
|
-
if (typeof arg1 == "function")
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
498
|
+
if (typeof arg1 == "function") {
|
|
499
|
+
let connect2 = function(model) {
|
|
500
|
+
reset = effect(model, (current) => {
|
|
501
|
+
proxy = current;
|
|
502
|
+
if (!reset)
|
|
503
|
+
compute2(true);
|
|
504
|
+
else if (STALE.delete(compute2))
|
|
505
|
+
compute2();
|
|
506
|
+
return (didUpdate) => {
|
|
507
|
+
if (didUpdate) {
|
|
508
|
+
STALE.add(compute2);
|
|
509
|
+
push(subject, key, true);
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
});
|
|
513
|
+
}, compute2 = function(initial) {
|
|
514
|
+
let next;
|
|
515
|
+
try {
|
|
516
|
+
next = getter.call(proxy, proxy, key);
|
|
517
|
+
} catch (err) {
|
|
518
|
+
console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key}.`);
|
|
519
|
+
if (initial)
|
|
520
|
+
throw err;
|
|
521
|
+
console.error(err);
|
|
493
522
|
}
|
|
523
|
+
update(subject, key, next, !isAsync);
|
|
494
524
|
};
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
514
|
-
if (STALE.delete(compute2))
|
|
515
|
-
compute2();
|
|
516
|
-
return fetch(subject, key, !proxy);
|
|
517
|
-
};
|
|
525
|
+
var connect = connect2, compute = compute2;
|
|
526
|
+
const getter = arg1;
|
|
527
|
+
let reset;
|
|
528
|
+
let isAsync;
|
|
529
|
+
let proxy;
|
|
530
|
+
return () => {
|
|
531
|
+
if (!proxy) {
|
|
532
|
+
source(connect2);
|
|
533
|
+
isAsync = true;
|
|
534
|
+
}
|
|
535
|
+
if (STALE.delete(compute2))
|
|
536
|
+
compute2();
|
|
537
|
+
return fetch(subject, key, !proxy);
|
|
538
|
+
};
|
|
539
|
+
} else
|
|
540
|
+
source((got) => subject.set(key, got));
|
|
541
|
+
return { get: arg1 };
|
|
542
|
+
});
|
|
518
543
|
}
|
|
519
544
|
|
|
520
545
|
// src/instruction/ref.ts
|
|
521
546
|
var define2 = Object.defineProperty;
|
|
522
547
|
function ref(arg, arg2) {
|
|
523
|
-
return
|
|
548
|
+
return use((key, subject, state) => {
|
|
524
549
|
let value = {};
|
|
525
550
|
if (arg === subject)
|
|
526
551
|
subject.get(() => {
|
|
@@ -570,7 +595,7 @@ function ref(arg, arg2) {
|
|
|
570
595
|
|
|
571
596
|
// src/instruction/set.ts
|
|
572
597
|
function set(value, argument) {
|
|
573
|
-
return
|
|
598
|
+
return use((key, subject) => {
|
|
574
599
|
const output = {};
|
|
575
600
|
if (typeof value == "function" || value instanceof Promise) {
|
|
576
601
|
let init2 = function() {
|
|
@@ -626,11 +651,11 @@ function set(value, argument) {
|
|
|
626
651
|
function attempt(fn) {
|
|
627
652
|
function retry(err) {
|
|
628
653
|
if (err instanceof Promise)
|
|
629
|
-
return err.then(
|
|
654
|
+
return err.then(compute);
|
|
630
655
|
else
|
|
631
656
|
throw err;
|
|
632
657
|
}
|
|
633
|
-
function
|
|
658
|
+
function compute() {
|
|
634
659
|
try {
|
|
635
660
|
const output = fn();
|
|
636
661
|
return output instanceof Promise ? output.catch(retry) : output;
|
|
@@ -638,27 +663,7 @@ function attempt(fn) {
|
|
|
638
663
|
return retry(err);
|
|
639
664
|
}
|
|
640
665
|
}
|
|
641
|
-
return
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
// src/instruction/use.ts
|
|
645
|
-
function use(value, argument) {
|
|
646
|
-
return add((property, subject) => {
|
|
647
|
-
if (typeof value === "function")
|
|
648
|
-
value = new value();
|
|
649
|
-
function set2(next) {
|
|
650
|
-
if (value instanceof Model && !(next instanceof value.constructor))
|
|
651
|
-
throw new Error(`${subject}.${property} expected Model of type ${value.constructor} but got ${next}.`);
|
|
652
|
-
if (next instanceof Model) {
|
|
653
|
-
PARENT.set(next, subject);
|
|
654
|
-
event(next, true);
|
|
655
|
-
}
|
|
656
|
-
if (typeof argument == "function")
|
|
657
|
-
argument(next);
|
|
658
|
-
}
|
|
659
|
-
set2(value);
|
|
660
|
-
return { set: set2, value };
|
|
661
|
-
});
|
|
666
|
+
return compute();
|
|
662
667
|
}
|
|
663
668
|
|
|
664
669
|
// src/context.ts
|
|
@@ -698,7 +703,7 @@ var Context = class {
|
|
|
698
703
|
throw new Error(`Did find ${Type} in context, but multiple were defined.`);
|
|
699
704
|
return result;
|
|
700
705
|
}
|
|
701
|
-
include(inputs) {
|
|
706
|
+
include(inputs, forEach) {
|
|
702
707
|
const init = /* @__PURE__ */ new Map();
|
|
703
708
|
if (typeof inputs == "function" || inputs instanceof Model)
|
|
704
709
|
inputs = { [0]: inputs };
|
|
@@ -718,10 +723,13 @@ var Context = class {
|
|
|
718
723
|
} else if (exists !== input) {
|
|
719
724
|
this.pop();
|
|
720
725
|
this.id = uid();
|
|
721
|
-
|
|
726
|
+
this.include(inputs);
|
|
722
727
|
}
|
|
723
728
|
}
|
|
724
|
-
for (const [model] of init) {
|
|
729
|
+
for (const [model, explicit] of init) {
|
|
730
|
+
if (forEach)
|
|
731
|
+
forEach(model, explicit);
|
|
732
|
+
model.set();
|
|
725
733
|
this.has(model);
|
|
726
734
|
const expects = Expects.get(model);
|
|
727
735
|
if (expects)
|
|
@@ -733,7 +741,6 @@ var Context = class {
|
|
|
733
741
|
init.set(value, false);
|
|
734
742
|
}
|
|
735
743
|
}
|
|
736
|
-
return init;
|
|
737
744
|
}
|
|
738
745
|
put(T, I, implicit, writable) {
|
|
739
746
|
do {
|
|
@@ -754,7 +761,7 @@ var Context = class {
|
|
|
754
761
|
let I;
|
|
755
762
|
if (typeof input == "function") {
|
|
756
763
|
T = input;
|
|
757
|
-
I = input
|
|
764
|
+
I = new input();
|
|
758
765
|
} else {
|
|
759
766
|
I = input;
|
|
760
767
|
T = I.constructor;
|
|
@@ -789,7 +796,7 @@ function reject(argument) {
|
|
|
789
796
|
|
|
790
797
|
// src/instruction/has.ts
|
|
791
798
|
function has(type, argument) {
|
|
792
|
-
return
|
|
799
|
+
return use((key, subject, state) => {
|
|
793
800
|
if (typeof argument == "boolean") {
|
|
794
801
|
Context.request(type, subject, (model) => {
|
|
795
802
|
subject.set(key, model);
|
|
@@ -830,7 +837,6 @@ function has(type, argument) {
|
|
|
830
837
|
export {
|
|
831
838
|
Context,
|
|
832
839
|
Model,
|
|
833
|
-
add,
|
|
834
840
|
Model as default,
|
|
835
841
|
get,
|
|
836
842
|
has,
|
package/package.json
CHANGED