@expressive/mvc 0.13.1 → 0.15.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/lib/index.d.ts +39 -19
- package/lib/index.esm.js +24 -13
- package/lib/index.js +24 -13
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -61,7 +61,10 @@ declare namespace Model {
|
|
|
61
61
|
export { Subscriber };
|
|
62
62
|
/** Including but not limited to T. */
|
|
63
63
|
type Extends<T> = T | (string & Record<never, never>);
|
|
64
|
-
|
|
64
|
+
/** Any typeof Model, using class constructor as the reference. */
|
|
65
|
+
export type Type<T extends Model = Model> = (new (...args: any[]) => T);
|
|
66
|
+
/** A typeof Model, specifically one which may be created without arguments. */
|
|
67
|
+
export type Constructor<T extends Model = Model> = (new () => T) & typeof Model;
|
|
65
68
|
export type Effect<T> = (this: T, argument: T) => Callback | Promise<any> | void;
|
|
66
69
|
/** Exotic value, actual value is contained. */
|
|
67
70
|
export type Ref<T = any> = {
|
|
@@ -105,7 +108,7 @@ declare namespace Model {
|
|
|
105
108
|
export type Get<T, K extends Key<T> = Key<T>> = {
|
|
106
109
|
[P in K]: Value<T[P]>;
|
|
107
110
|
};
|
|
108
|
-
export type Export<T
|
|
111
|
+
export type Export<T> = {
|
|
109
112
|
[P in Key<T>]: Value<T[P]>;
|
|
110
113
|
};
|
|
111
114
|
}
|
|
@@ -386,7 +389,7 @@ declare function use<T extends Model>(from: () => T, required: boolean): T;
|
|
|
386
389
|
/**
|
|
387
390
|
* Create a new child instance of model.
|
|
388
391
|
*/
|
|
389
|
-
declare function use<T extends Model>(Type: Model.
|
|
392
|
+
declare function use<T extends Model>(Type: Model.Constructor<T>, callback?: (i: T) => void): T;
|
|
390
393
|
/**
|
|
391
394
|
* Create a managed child from factory function.
|
|
392
395
|
*/
|
|
@@ -417,6 +420,22 @@ declare function has<T extends Model>(Type: Model.Type<T>, required?: true): T;
|
|
|
417
420
|
|
|
418
421
|
declare namespace MVC {
|
|
419
422
|
type EffectCallback<T = MVC> = (found: T) => Callback | void;
|
|
423
|
+
type ForceUpdate = {
|
|
424
|
+
/** Force an update in current component. */
|
|
425
|
+
(): void;
|
|
426
|
+
/**
|
|
427
|
+
* Force an update and again after promise either resolves or rejects.
|
|
428
|
+
* Will return a duplicate of given Promise, which resolves after refresh.
|
|
429
|
+
*/
|
|
430
|
+
<T = void>(passthru?: Promise<T>): Promise<T>;
|
|
431
|
+
/**
|
|
432
|
+
* Force a update while calling async function.
|
|
433
|
+
* A refresh will occur both before and after given function.
|
|
434
|
+
* Any actions performed before first `await` will occur before refresh!
|
|
435
|
+
*/
|
|
436
|
+
<T = void>(invoke?: () => Promise<T>): Promise<T>;
|
|
437
|
+
};
|
|
438
|
+
type TapCallback<T extends Model, R> = (this: T, model: T, update: MVC.ForceUpdate) => R;
|
|
420
439
|
}
|
|
421
440
|
declare class MVC extends Model {
|
|
422
441
|
end(force?: boolean): boolean | void;
|
|
@@ -457,11 +476,11 @@ declare class MVC extends Model {
|
|
|
457
476
|
static tap<T extends MVC>(this: Model.Type<T>): T;
|
|
458
477
|
static tap<T extends MVC, K extends Model.Key<T>>(this: Model.Type<T>, key: K, expect: true): Exclude<T[K], undefined>;
|
|
459
478
|
static tap<T extends MVC, K extends Model.Key<T>>(this: Model.Type<T>, key: K, expect?: boolean): NoVoid<T[K]>;
|
|
460
|
-
static tap<T extends MVC, R>(this: Model.Type<T>, connect:
|
|
461
|
-
static tap<T extends MVC, R>(this: Model.Type<T>, connect:
|
|
462
|
-
static tap<T extends MVC, R>(this: Model.Type<T>, compute:
|
|
463
|
-
static tap<T extends MVC, R>(this: Model.Type<T>, compute:
|
|
464
|
-
static tap<T extends MVC, R>(this: Model.Type<T>, compute:
|
|
479
|
+
static tap<T extends MVC, R>(this: Model.Type<T>, connect: MVC.TapCallback<T, () => R>): NoVoid<R>;
|
|
480
|
+
static tap<T extends MVC, R>(this: Model.Type<T>, connect: MVC.TapCallback<T, (() => R) | null>): NoVoid<R> | null;
|
|
481
|
+
static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, Promise<R> | R>, expect: true): Exclude<R, undefined>;
|
|
482
|
+
static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, Promise<R>>, expect?: boolean): NoVoid<R> | null;
|
|
483
|
+
static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, R>, expect?: boolean): NoVoid<R>;
|
|
465
484
|
static use<I extends MVC>(this: Model.Type<I>, watch: Model.Key<I>[], callback?: (instance: I) => void): I;
|
|
466
485
|
static use<I extends MVC>(this: Model.Type<I>, callback?: (instance: I) => void): I;
|
|
467
486
|
static use<I extends MVC>(this: Model.Type<I>, apply: Model.Compat<I>, keys?: Model.Event<I>[]): I;
|
|
@@ -477,21 +496,22 @@ declare class MVC extends Model {
|
|
|
477
496
|
declare function useContext<T extends Model>(Type: Model.Type<T>, required: false): T | undefined;
|
|
478
497
|
declare function useContext<T extends Model>(Type: Model.Type<T>, required?: boolean): T;
|
|
479
498
|
|
|
480
|
-
declare function useNew<T extends Model>(source: Model.
|
|
481
|
-
declare function useNew<T extends Model>(source: Model.
|
|
482
|
-
declare function useNew<T extends Model>(source: Model.
|
|
499
|
+
declare function useNew<T extends Model>(source: Model.Constructor<T> | (() => T), callback?: (instance: T) => void): T;
|
|
500
|
+
declare function useNew<T extends Model>(source: Model.Constructor<T> | (() => T), watch: Model.Key<T>[], callback?: (instance: T) => void): T;
|
|
501
|
+
declare function useNew<T extends Model>(source: Model.Constructor<T> | (() => T), apply: Model.Compat<T>, keys?: Model.Event<T>[]): T;
|
|
483
502
|
|
|
484
503
|
declare namespace useTap {
|
|
485
504
|
type Source<T extends Model> = T | Model.Type<T> | (() => T | Model.Type<T>);
|
|
505
|
+
type Callback<T extends Model, R> = (this: T, model: T, update: MVC.ForceUpdate) => R;
|
|
486
506
|
}
|
|
487
507
|
declare function useTap<T extends Model>(source: useTap.Source<T>): T;
|
|
488
508
|
declare function useTap<T extends Model, K extends Model.Key<T>>(source: useTap.Source<T>, path: K, expect: true): Exclude<T[K], undefined>;
|
|
489
509
|
declare function useTap<T extends Model, K extends Model.Key<T>>(source: useTap.Source<T>, path: K, expect?: boolean): NoVoid<T[K]>;
|
|
490
|
-
declare function useTap<T extends Model, R>(source: useTap.Source<T>, connect:
|
|
491
|
-
declare function useTap<T extends Model, R>(source: useTap.Source<T>, connect:
|
|
492
|
-
declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute:
|
|
493
|
-
declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute:
|
|
494
|
-
declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute:
|
|
510
|
+
declare function useTap<T extends Model, R>(source: useTap.Source<T>, connect: useTap.Callback<T, () => R>): NoVoid<R>;
|
|
511
|
+
declare function useTap<T extends Model, R>(source: useTap.Source<T>, connect: useTap.Callback<T, (() => R) | null>): NoVoid<R> | null;
|
|
512
|
+
declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: useTap.Callback<T, Promise<R> | R>, expect: true): Exclude<R, undefined>;
|
|
513
|
+
declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: useTap.Callback<T, Promise<R>>, expect?: boolean): NoVoid<R> | null;
|
|
514
|
+
declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: useTap.Callback<T, R>, expect?: boolean): NoVoid<R>;
|
|
495
515
|
|
|
496
516
|
declare namespace Consumer {
|
|
497
517
|
type HasProps<E extends Class> = {
|
|
@@ -531,7 +551,7 @@ declare namespace Consumer {
|
|
|
531
551
|
declare function Consumer<T extends Class>(props: Consumer.Props<T>): any;
|
|
532
552
|
|
|
533
553
|
declare namespace Provider {
|
|
534
|
-
type Item = Model | Model.
|
|
554
|
+
type Item = Model | Model.Constructor;
|
|
535
555
|
type Multiple<T extends Item = Item> = T[] | {
|
|
536
556
|
[key: string]: T;
|
|
537
557
|
};
|
|
@@ -540,13 +560,13 @@ declare namespace Provider {
|
|
|
540
560
|
for: E;
|
|
541
561
|
fallback?: React.ReactNode;
|
|
542
562
|
children?: React.ReactNode | ((instance: I) => React.ReactNode);
|
|
543
|
-
|
|
563
|
+
use?: Model.Compat<I>;
|
|
544
564
|
};
|
|
545
565
|
type MultipleProps<T extends Item> = {
|
|
546
566
|
for: Multiple<T>;
|
|
547
567
|
fallback?: React.ReactNode;
|
|
548
568
|
children?: React.ReactNode;
|
|
549
|
-
|
|
569
|
+
use?: Model.Compat<Instance<T>>;
|
|
550
570
|
};
|
|
551
571
|
type Props<T extends Item> = MultipleProps<T> | NormalProps<T>;
|
|
552
572
|
}
|
package/lib/index.esm.js
CHANGED
|
@@ -1354,10 +1354,18 @@ function useCompute(source, compute, suspend) {
|
|
|
1354
1354
|
const local = use(refresh => {
|
|
1355
1355
|
const sub = control(source).subscribe(() => update);
|
|
1356
1356
|
const spy = sub.proxy;
|
|
1357
|
-
let
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1357
|
+
let make = () => compute.call(spy, spy, forceUpdate);
|
|
1358
|
+
function forceUpdate(passthru) {
|
|
1359
|
+
if (typeof passthru == "function")
|
|
1360
|
+
passthru = passthru();
|
|
1361
|
+
if (make)
|
|
1362
|
+
reassign(make());
|
|
1363
|
+
else
|
|
1364
|
+
refresh();
|
|
1365
|
+
if (passthru)
|
|
1366
|
+
return passthru.finally(refresh);
|
|
1367
|
+
}
|
|
1368
|
+
function reassign(next) {
|
|
1361
1369
|
value = next;
|
|
1362
1370
|
if (retry) {
|
|
1363
1371
|
retry();
|
|
@@ -1365,13 +1373,14 @@ function useCompute(source, compute, suspend) {
|
|
|
1365
1373
|
}
|
|
1366
1374
|
else
|
|
1367
1375
|
refresh();
|
|
1368
|
-
}
|
|
1376
|
+
}
|
|
1377
|
+
let retry;
|
|
1378
|
+
let update;
|
|
1379
|
+
let value = make();
|
|
1369
1380
|
if (value === null) {
|
|
1370
1381
|
sub.watch.clear();
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
release: () => { }
|
|
1374
|
-
};
|
|
1382
|
+
make = undefined;
|
|
1383
|
+
return;
|
|
1375
1384
|
}
|
|
1376
1385
|
if (typeof value == "function") {
|
|
1377
1386
|
const get = value;
|
|
@@ -1380,15 +1389,15 @@ function useCompute(source, compute, suspend) {
|
|
|
1380
1389
|
value = get();
|
|
1381
1390
|
}
|
|
1382
1391
|
if (value instanceof Promise) {
|
|
1383
|
-
value.then(
|
|
1392
|
+
value.then(reassign);
|
|
1384
1393
|
value = undefined;
|
|
1385
1394
|
}
|
|
1386
1395
|
else {
|
|
1387
1396
|
sub.commit();
|
|
1388
1397
|
update = () => {
|
|
1389
|
-
const next =
|
|
1398
|
+
const next = make();
|
|
1390
1399
|
if (value != next)
|
|
1391
|
-
|
|
1400
|
+
reassign(next);
|
|
1392
1401
|
};
|
|
1393
1402
|
}
|
|
1394
1403
|
defineProperty(sub, "proxy", {
|
|
@@ -1402,6 +1411,8 @@ function useCompute(source, compute, suspend) {
|
|
|
1402
1411
|
});
|
|
1403
1412
|
return sub;
|
|
1404
1413
|
}, deps);
|
|
1414
|
+
if (!local)
|
|
1415
|
+
return null;
|
|
1405
1416
|
React.useLayoutEffect(() => local.release, deps);
|
|
1406
1417
|
return local.proxy;
|
|
1407
1418
|
}
|
|
@@ -1517,7 +1528,7 @@ const Oops = issues({
|
|
|
1517
1528
|
NoType: () => "Provider 'for' prop must be Model, typeof Model or a collection of them."
|
|
1518
1529
|
});
|
|
1519
1530
|
function Provider(props) {
|
|
1520
|
-
const context = useNewContext(props.for, props.
|
|
1531
|
+
const context = useNewContext(props.for, props.use);
|
|
1521
1532
|
return (React.createElement(LookupContext.Provider, { value: context }, props.fallback === false
|
|
1522
1533
|
? props.children
|
|
1523
1534
|
: (React.createElement(Suspense, { fallback: props.fallback || null }, props.children))));
|
package/lib/index.js
CHANGED
|
@@ -1362,10 +1362,18 @@ function useCompute(source, compute, suspend) {
|
|
|
1362
1362
|
const local = use(refresh => {
|
|
1363
1363
|
const sub = control(source).subscribe(() => update);
|
|
1364
1364
|
const spy = sub.proxy;
|
|
1365
|
-
let
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1365
|
+
let make = () => compute.call(spy, spy, forceUpdate);
|
|
1366
|
+
function forceUpdate(passthru) {
|
|
1367
|
+
if (typeof passthru == "function")
|
|
1368
|
+
passthru = passthru();
|
|
1369
|
+
if (make)
|
|
1370
|
+
reassign(make());
|
|
1371
|
+
else
|
|
1372
|
+
refresh();
|
|
1373
|
+
if (passthru)
|
|
1374
|
+
return passthru.finally(refresh);
|
|
1375
|
+
}
|
|
1376
|
+
function reassign(next) {
|
|
1369
1377
|
value = next;
|
|
1370
1378
|
if (retry) {
|
|
1371
1379
|
retry();
|
|
@@ -1373,13 +1381,14 @@ function useCompute(source, compute, suspend) {
|
|
|
1373
1381
|
}
|
|
1374
1382
|
else
|
|
1375
1383
|
refresh();
|
|
1376
|
-
}
|
|
1384
|
+
}
|
|
1385
|
+
let retry;
|
|
1386
|
+
let update;
|
|
1387
|
+
let value = make();
|
|
1377
1388
|
if (value === null) {
|
|
1378
1389
|
sub.watch.clear();
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
release: () => { }
|
|
1382
|
-
};
|
|
1390
|
+
make = undefined;
|
|
1391
|
+
return;
|
|
1383
1392
|
}
|
|
1384
1393
|
if (typeof value == "function") {
|
|
1385
1394
|
const get = value;
|
|
@@ -1388,15 +1397,15 @@ function useCompute(source, compute, suspend) {
|
|
|
1388
1397
|
value = get();
|
|
1389
1398
|
}
|
|
1390
1399
|
if (value instanceof Promise) {
|
|
1391
|
-
value.then(
|
|
1400
|
+
value.then(reassign);
|
|
1392
1401
|
value = undefined;
|
|
1393
1402
|
}
|
|
1394
1403
|
else {
|
|
1395
1404
|
sub.commit();
|
|
1396
1405
|
update = () => {
|
|
1397
|
-
const next =
|
|
1406
|
+
const next = make();
|
|
1398
1407
|
if (value != next)
|
|
1399
|
-
|
|
1408
|
+
reassign(next);
|
|
1400
1409
|
};
|
|
1401
1410
|
}
|
|
1402
1411
|
defineProperty(sub, "proxy", {
|
|
@@ -1410,6 +1419,8 @@ function useCompute(source, compute, suspend) {
|
|
|
1410
1419
|
});
|
|
1411
1420
|
return sub;
|
|
1412
1421
|
}, deps);
|
|
1422
|
+
if (!local)
|
|
1423
|
+
return null;
|
|
1413
1424
|
React__default["default"].useLayoutEffect(() => local.release, deps);
|
|
1414
1425
|
return local.proxy;
|
|
1415
1426
|
}
|
|
@@ -1525,7 +1536,7 @@ const Oops = issues({
|
|
|
1525
1536
|
NoType: () => "Provider 'for' prop must be Model, typeof Model or a collection of them."
|
|
1526
1537
|
});
|
|
1527
1538
|
function Provider(props) {
|
|
1528
|
-
const context = useNewContext(props.for, props.
|
|
1539
|
+
const context = useNewContext(props.for, props.use);
|
|
1529
1540
|
return (React__default["default"].createElement(LookupContext.Provider, { value: context }, props.fallback === false
|
|
1530
1541
|
? props.children
|
|
1531
1542
|
: (React__default["default"].createElement(React.Suspense, { fallback: props.fallback || null }, props.children))));
|
package/package.json
CHANGED