@expressive/mvc 0.11.1 → 0.12.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
@@ -484,15 +484,6 @@ declare class MVC extends Model {
484
484
  static meta<T, M extends Class>(this: M, from: (this: M, state: M) => T, expect?: boolean): T;
485
485
  }
486
486
 
487
- declare class Lookup {
488
- private table;
489
- get local(): Model[];
490
- private key;
491
- get(T: Model.Type): any;
492
- add(input: Model.Type | Model): void;
493
- push(): this;
494
- pop(): void;
495
- }
496
487
  declare function useContext<T extends Model>(Type: Model.Type<T>, required: false): T | undefined;
497
488
  declare function useContext<T extends Model>(Type: Model.Type<T>, required?: boolean): T;
498
489
 
@@ -557,17 +548,19 @@ declare namespace Provider {
557
548
  type Instance<E> = E extends Class ? InstanceType<E> : E extends Model ? E : never;
558
549
  type NormalProps<E, I = Instance<E>> = {
559
550
  for: E;
551
+ fallback?: React.ReactNode;
560
552
  children?: React.ReactNode | ((instance: I) => React.ReactNode);
561
553
  and?: Model.Compat<I>;
562
554
  };
563
555
  type MultipleProps<T extends Item> = {
564
556
  for: Multiple<T>;
565
- children?: React.ReactNode | (() => React.ReactNode);
557
+ fallback?: React.ReactNode;
558
+ children?: React.ReactNode;
566
559
  and?: Model.Compat<Instance<T>>;
567
560
  };
568
561
  type Props<T extends Item> = MultipleProps<T> | NormalProps<T>;
569
562
  }
570
- declare function Provider<T extends Provider.Item>(props: Provider.Props<T>): React.FunctionComponentElement<React.ProviderProps<Lookup>>;
563
+ declare function Provider<T extends Provider.Item>(props: Provider.Props<T>): JSX.Element;
571
564
 
572
565
  declare class Global extends MVC {
573
566
  static global: boolean;
package/lib/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useState, useMemo } from 'react';
1
+ import React, { useState, useMemo, Suspense } from 'react';
2
2
 
3
3
  const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
4
4
  function unique(array) {
@@ -770,13 +770,13 @@ function run(task) {
770
770
  const Oops$8 = issues({
771
771
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
772
772
  });
773
- function factoryMode(self, output, key, required) {
773
+ function factoryMode(self, value, key, required) {
774
774
  const { subject, state } = self;
775
775
  let pending;
776
776
  let error;
777
- if (output instanceof Promise) {
777
+ if (value instanceof Promise) {
778
778
  state.set(key, undefined);
779
- pending = output
779
+ pending = value
780
780
  .catch(err => error = err)
781
781
  .then(val => {
782
782
  state.set(key, val);
@@ -787,7 +787,8 @@ function factoryMode(self, output, key, required) {
787
787
  self.update(key);
788
788
  });
789
789
  }
790
- state.set(key, output);
790
+ else
791
+ state.set(key, value);
791
792
  const suspend = () => {
792
793
  if (required === false)
793
794
  return undefined;
@@ -1182,9 +1183,11 @@ class Lookup {
1182
1183
  let writable = true;
1183
1184
  let T;
1184
1185
  let I;
1186
+ if (MVC.isTypeof(input) && input.global)
1187
+ return input.new();
1185
1188
  if (typeof input == "function") {
1186
1189
  T = input;
1187
- I = input.new();
1190
+ I = new input();
1188
1191
  }
1189
1192
  else {
1190
1193
  I = input;
@@ -1201,10 +1204,7 @@ class Lookup {
1201
1204
  });
1202
1205
  T = getPrototypeOf(T);
1203
1206
  } while (T !== Model);
1204
- Control.for(I).state.forEach(value => {
1205
- if (Parent.get(value) === I)
1206
- this.add(value);
1207
- });
1207
+ return I;
1208
1208
  }
1209
1209
  push() {
1210
1210
  return create(this);
@@ -1492,11 +1492,10 @@ const Oops = issues({
1492
1492
  });
1493
1493
  function Provider(props) {
1494
1494
  const context = useNewContext(props.for, props.and);
1495
- const render = props.children;
1496
1495
  React.useLayoutEffect(() => () => context.pop(), []);
1497
- return React.createElement(LookupContext.Provider, { value: context }, typeof render == "function"
1498
- ? React.createElement(RenderFunction, { context, render })
1499
- : render);
1496
+ return (React.createElement(LookupContext.Provider, { value: context }, props.fallback === false
1497
+ ? props.children
1498
+ : (React.createElement(Suspense, { fallback: props.fallback || null }, props.children))));
1500
1499
  }
1501
1500
  function useNewContext(include, assign) {
1502
1501
  const ambient = useLookup();
@@ -1504,36 +1503,32 @@ function useNewContext(include, assign) {
1504
1503
  if (!include)
1505
1504
  throw Oops.NoType();
1506
1505
  const next = ambient.push();
1506
+ function register(T) {
1507
+ const i = next.add(T);
1508
+ if (assign)
1509
+ assignWeak(i, assign);
1510
+ Control.for(i).state.forEach(value => {
1511
+ if (Parent.get(value) === i)
1512
+ next.add(value);
1513
+ });
1514
+ }
1507
1515
  if (include instanceof Model || typeof include == "function")
1508
- next.add(include);
1516
+ register(include);
1509
1517
  else
1510
- values(include).forEach(x => next.add(x));
1518
+ values(include).forEach(register);
1511
1519
  for (const instance of next.local)
1512
- if (instance) {
1513
- if (assign)
1514
- assignWeak(instance, assign);
1520
+ if (instance)
1515
1521
  for (const apply of getPending(instance))
1516
1522
  apply(next);
1517
- }
1518
1523
  return next;
1519
1524
  }, []);
1520
1525
  if (assign)
1521
- for (const into of context.local)
1522
- if (into)
1523
- assignWeak(into, assign);
1526
+ context.local.forEach(i => {
1527
+ if (i && !Parent.has(i))
1528
+ assignWeak(i, assign);
1529
+ });
1524
1530
  return context;
1525
1531
  }
1526
- function RenderFunction(props) {
1527
- const hook = use(refresh => {
1528
- const targets = props.context.local;
1529
- if (targets.length == 1)
1530
- return Control.for(targets[0]).subscribe(() => refresh);
1531
- return {};
1532
- });
1533
- if (hook.commit)
1534
- React.useLayoutEffect(hook.commit, []);
1535
- return props.render(hook.proxy);
1536
- }
1537
1532
  function assignWeak(into, from) {
1538
1533
  for (const K in from)
1539
1534
  if (K in into)
package/lib/index.js CHANGED
@@ -778,13 +778,13 @@ function run(task) {
778
778
  const Oops$8 = issues({
779
779
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
780
780
  });
781
- function factoryMode(self, output, key, required) {
781
+ function factoryMode(self, value, key, required) {
782
782
  const { subject, state } = self;
783
783
  let pending;
784
784
  let error;
785
- if (output instanceof Promise) {
785
+ if (value instanceof Promise) {
786
786
  state.set(key, undefined);
787
- pending = output
787
+ pending = value
788
788
  .catch(err => error = err)
789
789
  .then(val => {
790
790
  state.set(key, val);
@@ -795,7 +795,8 @@ function factoryMode(self, output, key, required) {
795
795
  self.update(key);
796
796
  });
797
797
  }
798
- state.set(key, output);
798
+ else
799
+ state.set(key, value);
799
800
  const suspend = () => {
800
801
  if (required === false)
801
802
  return undefined;
@@ -1190,9 +1191,11 @@ class Lookup {
1190
1191
  let writable = true;
1191
1192
  let T;
1192
1193
  let I;
1194
+ if (MVC.isTypeof(input) && input.global)
1195
+ return input.new();
1193
1196
  if (typeof input == "function") {
1194
1197
  T = input;
1195
- I = input.new();
1198
+ I = new input();
1196
1199
  }
1197
1200
  else {
1198
1201
  I = input;
@@ -1209,10 +1212,7 @@ class Lookup {
1209
1212
  });
1210
1213
  T = getPrototypeOf(T);
1211
1214
  } while (T !== Model);
1212
- Control.for(I).state.forEach(value => {
1213
- if (Parent.get(value) === I)
1214
- this.add(value);
1215
- });
1215
+ return I;
1216
1216
  }
1217
1217
  push() {
1218
1218
  return create(this);
@@ -1500,11 +1500,10 @@ const Oops = issues({
1500
1500
  });
1501
1501
  function Provider(props) {
1502
1502
  const context = useNewContext(props.for, props.and);
1503
- const render = props.children;
1504
1503
  React__default["default"].useLayoutEffect(() => () => context.pop(), []);
1505
- return React__default["default"].createElement(LookupContext.Provider, { value: context }, typeof render == "function"
1506
- ? React__default["default"].createElement(RenderFunction, { context, render })
1507
- : render);
1504
+ return (React__default["default"].createElement(LookupContext.Provider, { value: context }, props.fallback === false
1505
+ ? props.children
1506
+ : (React__default["default"].createElement(React.Suspense, { fallback: props.fallback || null }, props.children))));
1508
1507
  }
1509
1508
  function useNewContext(include, assign) {
1510
1509
  const ambient = useLookup();
@@ -1512,36 +1511,32 @@ function useNewContext(include, assign) {
1512
1511
  if (!include)
1513
1512
  throw Oops.NoType();
1514
1513
  const next = ambient.push();
1514
+ function register(T) {
1515
+ const i = next.add(T);
1516
+ if (assign)
1517
+ assignWeak(i, assign);
1518
+ Control.for(i).state.forEach(value => {
1519
+ if (Parent.get(value) === i)
1520
+ next.add(value);
1521
+ });
1522
+ }
1515
1523
  if (include instanceof Model || typeof include == "function")
1516
- next.add(include);
1524
+ register(include);
1517
1525
  else
1518
- values(include).forEach(x => next.add(x));
1526
+ values(include).forEach(register);
1519
1527
  for (const instance of next.local)
1520
- if (instance) {
1521
- if (assign)
1522
- assignWeak(instance, assign);
1528
+ if (instance)
1523
1529
  for (const apply of getPending(instance))
1524
1530
  apply(next);
1525
- }
1526
1531
  return next;
1527
1532
  }, []);
1528
1533
  if (assign)
1529
- for (const into of context.local)
1530
- if (into)
1531
- assignWeak(into, assign);
1534
+ context.local.forEach(i => {
1535
+ if (i && !Parent.has(i))
1536
+ assignWeak(i, assign);
1537
+ });
1532
1538
  return context;
1533
1539
  }
1534
- function RenderFunction(props) {
1535
- const hook = use(refresh => {
1536
- const targets = props.context.local;
1537
- if (targets.length == 1)
1538
- return Control.for(targets[0]).subscribe(() => refresh);
1539
- return {};
1540
- });
1541
- if (hook.commit)
1542
- React__default["default"].useLayoutEffect(hook.commit, []);
1543
- return props.render(hook.proxy);
1544
- }
1545
1540
  function assignWeak(into, from) {
1546
1541
  for (const K in from)
1547
1542
  if (K in into)
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.11.1"
52
+ "version": "0.12.0"
53
53
  }