@expressive/mvc 1.0.0-beta.22 → 1.0.0-beta.23

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.js CHANGED
@@ -1080,51 +1080,76 @@ function from(source, setter, getter) {
1080
1080
  const Oops$1 = issues({
1081
1081
  ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
1082
1082
  });
1083
+ function pending(source, compute) {
1084
+ return (source === undefined ?
1085
+ suspendForValue() :
1086
+ typeof source == "function" && !source.prototype ?
1087
+ suspendForAsync(source) :
1088
+ suspendForComputed(source, compute));
1089
+ }
1083
1090
  /**
1084
- * Create suspense promise also interpretable as an error.
1085
- * React will handle it but other contexts probably won't.
1091
+ * Get value, suspend instead if undefined.
1092
+ *
1093
+ * Throws suspense promise also interpretable as an error.
1094
+ * React could handle it but other contexts probably not.
1086
1095
  */
1087
- function suspense(model, key) {
1088
- const { message, stack } = Oops$1.ValueNotReady(model, key);
1096
+ function pendingValue(via, key) {
1097
+ const value = via.state[key];
1098
+ if (value !== undefined)
1099
+ return value;
1100
+ const error = Oops$1.ValueNotReady(via.subject, key);
1089
1101
  const promise = new Promise(resolve => {
1090
- const release = model.on(key, (value) => {
1091
- if (value !== undefined)
1092
- release(), resolve();
1102
+ const release = via.addListener({
1103
+ [key](value) {
1104
+ if (value !== undefined) {
1105
+ release();
1106
+ resolve();
1107
+ }
1108
+ }
1093
1109
  });
1094
1110
  });
1095
- return Object.assign(promise, { message, stack });
1111
+ throw Object.assign(promise, {
1112
+ toString: () => String(error),
1113
+ message: error.message,
1114
+ stack: error.stack
1115
+ });
1096
1116
  }
1097
- function pending(source, compute) {
1098
- if (typeof source == "function" && !source.prototype)
1099
- return suspendForAsync(source);
1100
- else
1101
- return from(source, compute, function getter(value, key) {
1102
- if (value === undefined)
1103
- throw suspense(this, key);
1104
- return value;
1105
- });
1117
+ function suspendForComputed(source, compute) {
1118
+ function getter(_value, key) {
1119
+ return pendingValue(manage(this), key);
1120
+ }
1121
+ return from(source, compute, getter);
1122
+ }
1123
+ function suspendForValue() {
1124
+ return apply(function pending(key) {
1125
+ this.state[key] = undefined;
1126
+ return {
1127
+ set: this.setter(key),
1128
+ get: () => pendingValue(this, key)
1129
+ };
1130
+ });
1106
1131
  }
1107
1132
  function suspendForAsync(source) {
1108
1133
  return apply(function suspense(key) {
1134
+ const subject = this.subject;
1109
1135
  let waiting = true;
1110
- let output;
1136
+ let value;
1111
1137
  let error;
1112
1138
  return () => {
1113
- if (waiting) {
1114
- const issue = Oops$1.ValueNotReady(this.subject, key);
1115
- const promise = source
1116
- .call(this.subject, key)
1117
- .catch(err => error = err)
1118
- .then((value) => output = value)
1119
- .finally(() => waiting = false);
1120
- throw Object.assign(promise, {
1121
- message: issue.message,
1122
- stack: issue.stack
1123
- });
1124
- }
1125
1139
  if (error)
1126
1140
  throw error;
1127
- return output;
1141
+ if (!waiting)
1142
+ return value;
1143
+ const issue = Oops$1.ValueNotReady(subject, key);
1144
+ let suspend = source
1145
+ .call(subject, key)
1146
+ .catch(err => error = err)
1147
+ .then(out => value = out)
1148
+ .finally(() => waiting = false);
1149
+ throw Object.assign(suspend, {
1150
+ message: issue.message,
1151
+ stack: issue.stack
1152
+ });
1128
1153
  };
1129
1154
  });
1130
1155
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@expressive/mvc",
3
+ "version": "1.0.0-beta.23",
3
4
  "description": "Use classes to define state in React!",
4
- "version": "1.0.0-beta.22",
5
5
  "author": {
6
6
  "name": "Gabe Klein",
7
7
  "email": "gabe@termtm.com",
@@ -50,7 +50,10 @@
50
50
  },
51
51
  "release": {
52
52
  "branches": [
53
- { "name": "beta", "prerelease": true }
53
+ {
54
+ "name": "beta",
55
+ "prerelease": true
56
+ }
54
57
  ]
55
58
  }
56
59
  }
@@ -1,9 +1,7 @@
1
- import { Consumer, ReactElement, ReactNode, Component, ComponentType } from "react";
1
+ import { Consumer, ReactElement, ReactNode } from "react";
2
2
  import { Model } from "./model"
3
3
  import { Class } from "./types";
4
4
 
5
- type Output = ReactElement<any, any> | null;
6
-
7
5
  export namespace Provider {
8
6
  type Item = Model | typeof Model;
9
7
  type Collection<T extends Item> = T[] | { [key: string]: T };
@@ -21,7 +19,7 @@ export namespace Provider {
21
19
  type Props<T extends Item> = MultipleProps<T> | NormalProps<T>;
22
20
  }
23
21
 
24
- export function Provider<T extends Provider.Item>(props: Provider.Props<T>): Output;
22
+ export function Provider<T extends Provider.Item>(props: Provider.Props<T>): ReactElement<typeof props>;
25
23
 
26
24
  export namespace Consumer {
27
25
  type HasProps<E extends Class> = {
@@ -50,10 +48,10 @@ export namespace Consumer {
50
48
  * Similar to `tap()`, updates to properties accessed in
51
49
  * this function will cause a refresh when they change.
52
50
  */
53
- children: (value: InstanceType<E>) => Output;
51
+ children: (value: InstanceType<E>) => ReactElement<any, any> | null;
54
52
  }
55
53
 
56
54
  type Props<T extends Class> = HasProps<T> | GetProps<T> | RenderProps<T>
57
55
  }
58
56
 
59
- export function Consumer<T extends Class>(props: Consumer.Props<T>): Output;
57
+ export function Consumer<T extends Class>(props: Consumer.Props<T>): null;
@@ -194,6 +194,12 @@ export function memo <T> (compute: () => T, lazy?: boolean): T;
194
194
  */
195
195
  export function lazy <T> (value?: T): T;
196
196
 
197
+ /**
198
+ * Pending value. Will suspend unless value is defined,
199
+ * suspense resolves when a value is aquired.
200
+ */
201
+ export function pending <T = boolean> (): Exclude<T, undefined>;
202
+
197
203
  /**
198
204
  * Suspend during the execution of given function to obtain value.
199
205
  *