@expressive/mvc 0.13.1 → 0.14.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 CHANGED
@@ -417,6 +417,11 @@ declare function has<T extends Model>(Type: Model.Type<T>, required?: true): T;
417
417
 
418
418
  declare namespace MVC {
419
419
  type EffectCallback<T = MVC> = (found: T) => Callback | void;
420
+ type ForceUpdate = {
421
+ (): void;
422
+ <T = void>(passthru?: Promise<T>): Promise<T>;
423
+ };
424
+ type TapCallback<T extends Model, R> = (this: T, model: T, update: MVC.ForceUpdate) => R;
420
425
  }
421
426
  declare class MVC extends Model {
422
427
  end(force?: boolean): boolean | void;
@@ -457,11 +462,11 @@ declare class MVC extends Model {
457
462
  static tap<T extends MVC>(this: Model.Type<T>): T;
458
463
  static tap<T extends MVC, K extends Model.Key<T>>(this: Model.Type<T>, key: K, expect: true): Exclude<T[K], undefined>;
459
464
  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: (this: T, model: T) => () => R): NoVoid<R>;
461
- static tap<T extends MVC, R>(this: Model.Type<T>, connect: (this: T, model: T) => (() => R) | null): NoVoid<R> | null;
462
- static tap<T extends MVC, R>(this: Model.Type<T>, compute: (this: T, model: T) => Promise<R> | R, expect: true): Exclude<R, undefined>;
463
- static tap<T extends MVC, R>(this: Model.Type<T>, compute: (this: T, model: T) => Promise<R>, expect?: boolean): NoVoid<R> | null;
464
- static tap<T extends MVC, R>(this: Model.Type<T>, compute: (this: T, model: T) => R, expect?: boolean): NoVoid<R>;
465
+ static tap<T extends MVC, R>(this: Model.Type<T>, connect: MVC.TapCallback<T, () => R>): NoVoid<R>;
466
+ static tap<T extends MVC, R>(this: Model.Type<T>, connect: MVC.TapCallback<T, (() => R) | null>): NoVoid<R> | null;
467
+ static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, Promise<R> | R>, expect: true): Exclude<R, undefined>;
468
+ static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, Promise<R>>, expect?: boolean): NoVoid<R> | null;
469
+ static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, R>, expect?: boolean): NoVoid<R>;
465
470
  static use<I extends MVC>(this: Model.Type<I>, watch: Model.Key<I>[], callback?: (instance: I) => void): I;
466
471
  static use<I extends MVC>(this: Model.Type<I>, callback?: (instance: I) => void): I;
467
472
  static use<I extends MVC>(this: Model.Type<I>, apply: Model.Compat<I>, keys?: Model.Event<I>[]): I;
@@ -483,15 +488,16 @@ declare function useNew<T extends Model>(source: Model.Type<T> | (() => T), appl
483
488
 
484
489
  declare namespace useTap {
485
490
  type Source<T extends Model> = T | Model.Type<T> | (() => T | Model.Type<T>);
491
+ type Callback<T extends Model, R> = (this: T, model: T, update: MVC.ForceUpdate) => R;
486
492
  }
487
493
  declare function useTap<T extends Model>(source: useTap.Source<T>): T;
488
494
  declare function useTap<T extends Model, K extends Model.Key<T>>(source: useTap.Source<T>, path: K, expect: true): Exclude<T[K], undefined>;
489
495
  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: (this: T, model: T) => () => R): NoVoid<R>;
491
- declare function useTap<T extends Model, R>(source: useTap.Source<T>, connect: (this: T, model: T) => (() => R) | null): NoVoid<R> | null;
492
- declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: (this: T, model: T) => Promise<R> | R, expect: true): Exclude<R, undefined>;
493
- declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: (this: T, model: T) => Promise<R>, expect?: boolean): NoVoid<R> | null;
494
- declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: (this: T, model: T) => R, expect?: boolean): NoVoid<R>;
496
+ declare function useTap<T extends Model, R>(source: useTap.Source<T>, connect: useTap.Callback<T, () => R>): NoVoid<R>;
497
+ declare function useTap<T extends Model, R>(source: useTap.Source<T>, connect: useTap.Callback<T, (() => R) | null>): NoVoid<R> | null;
498
+ declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: useTap.Callback<T, Promise<R> | R>, expect: true): Exclude<R, undefined>;
499
+ declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: useTap.Callback<T, Promise<R>>, expect?: boolean): NoVoid<R> | null;
500
+ declare function useTap<T extends Model, R>(source: useTap.Source<T>, compute: useTap.Callback<T, R>, expect?: boolean): NoVoid<R>;
495
501
 
496
502
  declare namespace Consumer {
497
503
  type HasProps<E extends Class> = {
package/lib/index.esm.js CHANGED
@@ -1354,10 +1354,16 @@ 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 value = compute.call(spy, spy);
1358
- let update;
1359
- let retry;
1360
- const set = (next) => {
1357
+ let make = () => compute.call(spy, spy, forceUpdate);
1358
+ function forceUpdate(passthru) {
1359
+ if (make)
1360
+ reassign(make());
1361
+ else
1362
+ refresh();
1363
+ if (passthru)
1364
+ return passthru.finally(refresh);
1365
+ }
1366
+ function reassign(next) {
1361
1367
  value = next;
1362
1368
  if (retry) {
1363
1369
  retry();
@@ -1365,13 +1371,14 @@ function useCompute(source, compute, suspend) {
1365
1371
  }
1366
1372
  else
1367
1373
  refresh();
1368
- };
1374
+ }
1375
+ let retry;
1376
+ let update;
1377
+ let value = make();
1369
1378
  if (value === null) {
1370
1379
  sub.watch.clear();
1371
- return {
1372
- proxy: null,
1373
- release: () => { }
1374
- };
1380
+ make = undefined;
1381
+ return;
1375
1382
  }
1376
1383
  if (typeof value == "function") {
1377
1384
  const get = value;
@@ -1380,15 +1387,15 @@ function useCompute(source, compute, suspend) {
1380
1387
  value = get();
1381
1388
  }
1382
1389
  if (value instanceof Promise) {
1383
- value.then(set);
1390
+ value.then(reassign);
1384
1391
  value = undefined;
1385
1392
  }
1386
1393
  else {
1387
1394
  sub.commit();
1388
1395
  update = () => {
1389
- const next = compute.call(spy, spy);
1396
+ const next = make();
1390
1397
  if (value != next)
1391
- set(next);
1398
+ reassign(next);
1392
1399
  };
1393
1400
  }
1394
1401
  defineProperty(sub, "proxy", {
@@ -1402,6 +1409,8 @@ function useCompute(source, compute, suspend) {
1402
1409
  });
1403
1410
  return sub;
1404
1411
  }, deps);
1412
+ if (!local)
1413
+ return null;
1405
1414
  React.useLayoutEffect(() => local.release, deps);
1406
1415
  return local.proxy;
1407
1416
  }
package/lib/index.js CHANGED
@@ -1362,10 +1362,16 @@ 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 value = compute.call(spy, spy);
1366
- let update;
1367
- let retry;
1368
- const set = (next) => {
1365
+ let make = () => compute.call(spy, spy, forceUpdate);
1366
+ function forceUpdate(passthru) {
1367
+ if (make)
1368
+ reassign(make());
1369
+ else
1370
+ refresh();
1371
+ if (passthru)
1372
+ return passthru.finally(refresh);
1373
+ }
1374
+ function reassign(next) {
1369
1375
  value = next;
1370
1376
  if (retry) {
1371
1377
  retry();
@@ -1373,13 +1379,14 @@ function useCompute(source, compute, suspend) {
1373
1379
  }
1374
1380
  else
1375
1381
  refresh();
1376
- };
1382
+ }
1383
+ let retry;
1384
+ let update;
1385
+ let value = make();
1377
1386
  if (value === null) {
1378
1387
  sub.watch.clear();
1379
- return {
1380
- proxy: null,
1381
- release: () => { }
1382
- };
1388
+ make = undefined;
1389
+ return;
1383
1390
  }
1384
1391
  if (typeof value == "function") {
1385
1392
  const get = value;
@@ -1388,15 +1395,15 @@ function useCompute(source, compute, suspend) {
1388
1395
  value = get();
1389
1396
  }
1390
1397
  if (value instanceof Promise) {
1391
- value.then(set);
1398
+ value.then(reassign);
1392
1399
  value = undefined;
1393
1400
  }
1394
1401
  else {
1395
1402
  sub.commit();
1396
1403
  update = () => {
1397
- const next = compute.call(spy, spy);
1404
+ const next = make();
1398
1405
  if (value != next)
1399
- set(next);
1406
+ reassign(next);
1400
1407
  };
1401
1408
  }
1402
1409
  defineProperty(sub, "proxy", {
@@ -1410,6 +1417,8 @@ function useCompute(source, compute, suspend) {
1410
1417
  });
1411
1418
  return sub;
1412
1419
  }, deps);
1420
+ if (!local)
1421
+ return null;
1413
1422
  React__default["default"].useLayoutEffect(() => local.release, deps);
1414
1423
  return local.proxy;
1415
1424
  }
package/package.json CHANGED
@@ -49,5 +49,5 @@
49
49
  "tslib": "^2.3.0",
50
50
  "typescript": "4.6.3"
51
51
  },
52
- "version": "0.13.1"
52
+ "version": "0.14.0"
53
53
  }