@expressive/mvc 0.6.3 → 0.7.2
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 +27 -21
- package/lib/index.esm.js +66 -71
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +66 -71
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/lib/index.d.ts
CHANGED
|
@@ -53,11 +53,6 @@ declare namespace Model {
|
|
|
53
53
|
export type Methods<T> = {
|
|
54
54
|
[K in keyof T]: T[K] extends Ref ? never : T[K] extends Function ? K : never;
|
|
55
55
|
}[keyof T];
|
|
56
|
-
export type Refs<T extends Model> = {
|
|
57
|
-
<K extends Field<T>>(key: K, value: T[K]): void;
|
|
58
|
-
} & {
|
|
59
|
-
[P in Field<T>]: (next: any) => void;
|
|
60
|
-
};
|
|
61
56
|
/**
|
|
62
57
|
* Subset of `keyof T` which are not methods or defined by base Model U.
|
|
63
58
|
*
|
|
@@ -92,13 +87,6 @@ interface Model extends Stateful {
|
|
|
92
87
|
* Useful to obtain full reference where one has already destructured.
|
|
93
88
|
*/
|
|
94
89
|
is: this;
|
|
95
|
-
/**
|
|
96
|
-
* Setter utility
|
|
97
|
-
*
|
|
98
|
-
* Can be used to set (and force-update) values.
|
|
99
|
-
* Shortcut to update values, contains refs for all controlled values.
|
|
100
|
-
*/
|
|
101
|
-
set: Model.Refs<this>;
|
|
102
90
|
}
|
|
103
91
|
declare class Model {
|
|
104
92
|
static [WHY]: readonly string[];
|
|
@@ -145,7 +133,7 @@ declare class Model {
|
|
|
145
133
|
*
|
|
146
134
|
* @param args - arguments sent to constructor
|
|
147
135
|
*/
|
|
148
|
-
static create<T extends Class>(this: T, ...args:
|
|
136
|
+
static create<T extends Class>(this: T, ...args: ConstructorParameters<T>): InstanceOf<T>;
|
|
149
137
|
/**
|
|
150
138
|
* Static equivalent of `x instanceof this`.
|
|
151
139
|
*
|
|
@@ -298,9 +286,30 @@ declare namespace ref {
|
|
|
298
286
|
}
|
|
299
287
|
/** Object with references to all managed values of `T`. */
|
|
300
288
|
type Proxy<T extends Model> = {
|
|
301
|
-
[P in Model.Field<T>]
|
|
289
|
+
[P in Model.Field<T>]-?: Model.Ref<T[P]>;
|
|
290
|
+
};
|
|
291
|
+
type CustomProxy<T extends Model, R> = {
|
|
292
|
+
[P in Model.Field<T>]-?: R;
|
|
302
293
|
};
|
|
303
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Creates an object with references to all managed values.
|
|
297
|
+
* Each property is a function to set value in state when invoked.
|
|
298
|
+
*
|
|
299
|
+
* *Properties are simultaneously a ref-function and ref-object, use as needed.*
|
|
300
|
+
*
|
|
301
|
+
* @param target - Source model from which to reference values.
|
|
302
|
+
*/
|
|
303
|
+
declare function ref<T extends Model>(target: T): ref.Proxy<T>;
|
|
304
|
+
/**
|
|
305
|
+
* Creates an object with values based on managed values.
|
|
306
|
+
* Each property will invoke mapper function on first access supply
|
|
307
|
+
* the its return value going forward.
|
|
308
|
+
*
|
|
309
|
+
* @param target - Source model from which to reference values.
|
|
310
|
+
* @param mapper - Function producing the placeholder value for any given property.
|
|
311
|
+
*/
|
|
312
|
+
declare function ref<O extends Model, R>(target: O, mapper: (key: Model.Field<O>) => R): ref.CustomProxy<O, R>;
|
|
304
313
|
/**
|
|
305
314
|
* Creates a ref-compatible property.
|
|
306
315
|
* Will persist value, and updates to this are made part of controller event-stream.
|
|
@@ -497,16 +506,13 @@ declare namespace Consumer {
|
|
|
497
506
|
}
|
|
498
507
|
declare function Consumer<T extends Class>(props: Consumer.Props<T>): any;
|
|
499
508
|
|
|
500
|
-
declare type Collection = Array<Model | typeof Model> | {
|
|
501
|
-
[anything: string]: Model | typeof Model;
|
|
502
|
-
};
|
|
503
509
|
declare class Lookup {
|
|
504
510
|
private table;
|
|
505
511
|
get local(): Model[];
|
|
506
512
|
private key;
|
|
507
513
|
get(T: typeof Model): any;
|
|
508
|
-
push(
|
|
509
|
-
|
|
514
|
+
push(): this;
|
|
515
|
+
inject(T: typeof Model, I: Model, writable?: boolean): void;
|
|
510
516
|
pop(): void;
|
|
511
517
|
}
|
|
512
518
|
|
|
@@ -533,13 +539,13 @@ declare namespace Provider {
|
|
|
533
539
|
declare function Provider<T extends Provider.Item>(props: Provider.Props<T>): React.FunctionComponentElement<React.ProviderProps<Lookup>>;
|
|
534
540
|
|
|
535
541
|
declare class Global extends MVC {
|
|
536
|
-
static create<T extends Class>(this: T, ...args:
|
|
542
|
+
static create<T extends Class>(this: T, ...args: ConstructorParameters<T>): InstanceOf<T>;
|
|
537
543
|
/**
|
|
538
544
|
* Update the active instance of this class.
|
|
539
545
|
* Returns a thenable; resolves after successful update.
|
|
540
546
|
* If instance does not already exist, one will be created.
|
|
541
547
|
*/
|
|
542
|
-
static set<T extends typeof Global>(this: T, updates: Partial<InstanceOf<T>>):
|
|
548
|
+
static set<T extends typeof Global>(this: T, updates: Partial<InstanceOf<T>>): any;
|
|
543
549
|
/**
|
|
544
550
|
* **React Hook** - Fetch most instance of this controller from context, if it exists.
|
|
545
551
|
*
|
package/lib/index.esm.js
CHANGED
|
@@ -196,22 +196,6 @@ class Model {
|
|
|
196
196
|
defineProperty(this, "is", {
|
|
197
197
|
value: this
|
|
198
198
|
});
|
|
199
|
-
defineProperty(this, "set", {
|
|
200
|
-
configurable: true,
|
|
201
|
-
get: () => {
|
|
202
|
-
const controller = ensure(this);
|
|
203
|
-
const value = (key, value) => {
|
|
204
|
-
controller.state.set(key, value);
|
|
205
|
-
controller.update(key);
|
|
206
|
-
};
|
|
207
|
-
for (const key of controller.state.keys())
|
|
208
|
-
defineProperty(value, key, {
|
|
209
|
-
value: controller.ref(key)
|
|
210
|
-
});
|
|
211
|
-
defineProperty(this, "set", { value });
|
|
212
|
-
return value;
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
199
|
}
|
|
216
200
|
get [STATE]() {
|
|
217
201
|
return this.export();
|
|
@@ -474,8 +458,11 @@ class Controller {
|
|
|
474
458
|
return;
|
|
475
459
|
if (typeof value == "symbol") {
|
|
476
460
|
const instruction = PENDING.get(value);
|
|
477
|
-
if (instruction)
|
|
461
|
+
if (instruction) {
|
|
462
|
+
delete subject[key];
|
|
463
|
+
PENDING.delete(value);
|
|
478
464
|
instruction.call(this, key, this);
|
|
465
|
+
}
|
|
479
466
|
return;
|
|
480
467
|
}
|
|
481
468
|
state.set(key, value);
|
|
@@ -579,9 +566,6 @@ function apply(fn, label) {
|
|
|
579
566
|
const placeholder = Symbol(`${name} instruction`);
|
|
580
567
|
function setup(key) {
|
|
581
568
|
const { subject, state } = this;
|
|
582
|
-
const control = this;
|
|
583
|
-
PENDING.delete(placeholder);
|
|
584
|
-
delete subject[key];
|
|
585
569
|
let output = fn.call(this, key, this);
|
|
586
570
|
if (typeof output == "function")
|
|
587
571
|
output = { get: output };
|
|
@@ -604,6 +588,7 @@ function apply(fn, label) {
|
|
|
604
588
|
destroy();
|
|
605
589
|
});
|
|
606
590
|
}
|
|
591
|
+
const control = this;
|
|
607
592
|
defineProperty(subject, key, {
|
|
608
593
|
enumerable: output.enumerable,
|
|
609
594
|
set: onSet !== false
|
|
@@ -797,7 +782,7 @@ function get(arg0, arg1, arg2) {
|
|
|
797
782
|
throw new Error(`Factory argument cannot be ${arg1}`);
|
|
798
783
|
getter = computeMode(this, source, setter, key, computeRequired);
|
|
799
784
|
};
|
|
800
|
-
if (typeof arg0 == "function" &&
|
|
785
|
+
if (typeof arg0 == "function" && computeRequired)
|
|
801
786
|
try {
|
|
802
787
|
init();
|
|
803
788
|
}
|
|
@@ -813,18 +798,34 @@ function get(arg0, arg1, arg2) {
|
|
|
813
798
|
});
|
|
814
799
|
}
|
|
815
800
|
|
|
816
|
-
function ref(
|
|
801
|
+
function ref(arg, mapper) {
|
|
817
802
|
return apply(function ref(key) {
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
803
|
+
let value = {};
|
|
804
|
+
if (typeof arg != "object")
|
|
805
|
+
value = createRef(this, key, arg);
|
|
806
|
+
else
|
|
807
|
+
ensure(arg).state.forEach((_val, key) => {
|
|
808
|
+
defineProperty(value, key, mapper ? {
|
|
809
|
+
configurable: true,
|
|
810
|
+
get() {
|
|
811
|
+
const out = mapper(key);
|
|
812
|
+
defineProperty(value, key, { value: out });
|
|
813
|
+
return out;
|
|
814
|
+
}
|
|
815
|
+
} : {
|
|
816
|
+
value: createRef(this, key)
|
|
817
|
+
});
|
|
818
|
+
});
|
|
819
|
+
return { value, explicit: true };
|
|
827
820
|
});
|
|
821
|
+
}
|
|
822
|
+
function createRef(src, key, cb) {
|
|
823
|
+
const refObjectFunction = src.ref(key, cb && createValueEffect(cb));
|
|
824
|
+
defineProperty(refObjectFunction, "current", {
|
|
825
|
+
set: refObjectFunction,
|
|
826
|
+
get: () => src.state.get(key)
|
|
827
|
+
});
|
|
828
|
+
return refObjectFunction;
|
|
828
829
|
}
|
|
829
830
|
|
|
830
831
|
function set(value, argument) {
|
|
@@ -921,12 +922,15 @@ function createProxy(emit, watch) {
|
|
|
921
922
|
assign(proxy, {
|
|
922
923
|
from,
|
|
923
924
|
delete(key) {
|
|
925
|
+
// TODO: this commit's fix needs tests.
|
|
926
|
+
// Was not cause by coverage.
|
|
927
|
+
const out = from.delete(key);
|
|
924
928
|
emit(key);
|
|
925
|
-
return
|
|
929
|
+
return out;
|
|
926
930
|
},
|
|
927
931
|
clear() {
|
|
928
|
-
emit(ANY);
|
|
929
932
|
from.clear();
|
|
933
|
+
emit(ANY);
|
|
930
934
|
},
|
|
931
935
|
has(key) {
|
|
932
936
|
watch(this, key);
|
|
@@ -1106,26 +1110,10 @@ class Lookup {
|
|
|
1106
1110
|
get(T) {
|
|
1107
1111
|
return this[this.key(T)];
|
|
1108
1112
|
}
|
|
1109
|
-
push(
|
|
1110
|
-
|
|
1111
|
-
if (I instanceof Model || typeof I == "function")
|
|
1112
|
-
next.register(I);
|
|
1113
|
-
else
|
|
1114
|
-
for (const i of values(I))
|
|
1115
|
-
next.register(i);
|
|
1116
|
-
return next;
|
|
1113
|
+
push() {
|
|
1114
|
+
return create(this);
|
|
1117
1115
|
}
|
|
1118
|
-
|
|
1119
|
-
let writable = true;
|
|
1120
|
-
let T;
|
|
1121
|
-
if (I instanceof Model) {
|
|
1122
|
-
T = I.constructor;
|
|
1123
|
-
writable = false;
|
|
1124
|
-
}
|
|
1125
|
-
else {
|
|
1126
|
-
T = I;
|
|
1127
|
-
I = I.create();
|
|
1128
|
-
}
|
|
1116
|
+
inject(T, I, writable) {
|
|
1129
1117
|
do {
|
|
1130
1118
|
const key = this.key(T);
|
|
1131
1119
|
const conflict = this.hasOwnProperty(key);
|
|
@@ -1136,7 +1124,6 @@ class Lookup {
|
|
|
1136
1124
|
});
|
|
1137
1125
|
T = getPrototypeOf(T);
|
|
1138
1126
|
} while (T !== Model);
|
|
1139
|
-
return I;
|
|
1140
1127
|
}
|
|
1141
1128
|
pop() {
|
|
1142
1129
|
for (const key of getOwnPropertySymbols(this)) {
|
|
@@ -1419,7 +1406,28 @@ const Oops$1 = issues({
|
|
|
1419
1406
|
function Provider(props) {
|
|
1420
1407
|
if ("of" in props)
|
|
1421
1408
|
throw Oops$1.PropDeprecated();
|
|
1422
|
-
const
|
|
1409
|
+
const from = useLookup();
|
|
1410
|
+
const context = React.useMemo(() => {
|
|
1411
|
+
const I = props.for;
|
|
1412
|
+
if (!I)
|
|
1413
|
+
throw Oops$1.NoType();
|
|
1414
|
+
const layer = from.push();
|
|
1415
|
+
function register(I) {
|
|
1416
|
+
if (I instanceof Model)
|
|
1417
|
+
layer.inject(I.constructor, I, false);
|
|
1418
|
+
else
|
|
1419
|
+
layer.inject(I, I.create(), true);
|
|
1420
|
+
}
|
|
1421
|
+
if (I instanceof Model || typeof I == "function")
|
|
1422
|
+
register(I);
|
|
1423
|
+
else
|
|
1424
|
+
values(I).forEach(register);
|
|
1425
|
+
for (const instance of layer.local)
|
|
1426
|
+
if (instance)
|
|
1427
|
+
for (const apply of getPending(instance))
|
|
1428
|
+
apply(layer);
|
|
1429
|
+
return layer;
|
|
1430
|
+
}, []);
|
|
1423
1431
|
const render = props.children;
|
|
1424
1432
|
useAppliedProps(context, props);
|
|
1425
1433
|
React.useLayoutEffect(() => () => context.pop(), []);
|
|
@@ -1427,19 +1435,6 @@ function Provider(props) {
|
|
|
1427
1435
|
? React.createElement(RenderFunction, { context, render })
|
|
1428
1436
|
: render);
|
|
1429
1437
|
}
|
|
1430
|
-
function useNewContext(inject) {
|
|
1431
|
-
const from = useLookup();
|
|
1432
|
-
return React.useMemo(() => {
|
|
1433
|
-
if (!inject)
|
|
1434
|
-
throw Oops$1.NoType();
|
|
1435
|
-
const context = from.push(inject);
|
|
1436
|
-
for (const instance of context.local)
|
|
1437
|
-
if (instance)
|
|
1438
|
-
for (const apply of getPending(instance))
|
|
1439
|
-
apply(context);
|
|
1440
|
-
return context;
|
|
1441
|
-
}, []);
|
|
1442
|
-
}
|
|
1443
1438
|
function useAppliedProps(within, props) {
|
|
1444
1439
|
const update = React.useMemo(() => {
|
|
1445
1440
|
const targets = within.local;
|
|
@@ -1472,11 +1467,11 @@ const Oops = issues({
|
|
|
1472
1467
|
const Active = new WeakMap();
|
|
1473
1468
|
class Global extends MVC {
|
|
1474
1469
|
static create(...args) {
|
|
1475
|
-
|
|
1476
|
-
if (Active.has(Type))
|
|
1470
|
+
if (Active.has(this))
|
|
1477
1471
|
throw Oops.AlreadyExists(this.name);
|
|
1478
|
-
const instance =
|
|
1479
|
-
|
|
1472
|
+
const instance = new this(...args);
|
|
1473
|
+
ensure(instance);
|
|
1474
|
+
Active.set(this, instance);
|
|
1480
1475
|
return instance;
|
|
1481
1476
|
}
|
|
1482
1477
|
/**
|