@expressive/mvc 0.6.0 → 0.6.3

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
@@ -229,10 +229,8 @@ declare function act<S>(action: Async<S>): typeof action & {
229
229
  };
230
230
 
231
231
  declare namespace get {
232
- type Function<T, O = any> = (this: O, on: O) => T;
233
- type Factory<T, O = any> = (key: string) => Function<T, O>;
234
- type Getter = (controller: Controller, key: string) => any;
235
- type Factory2<T, S = unknown> = (this: S, key: string, thisArg: S) => T;
232
+ type Function<T, S = any> = (this: S, on: S) => T;
233
+ type Factory<T, S = unknown> = (this: S, key: string, thisArg: S) => T;
236
234
  }
237
235
  /**
238
236
  * Implement a computed value; output will be generated by provided function.
@@ -249,43 +247,43 @@ declare function get<R, T>(source: T, compute: (this: T, on: T) => R, suspend?:
249
247
  * @param compute - Factory function to generate a getter to subscribe dependancies.
250
248
  * @param suspend - Value will throw suspense when evaulating to undefined.
251
249
  */
252
- declare function get<R, T>(compute: (property: string) => (this: T, state: T) => R, suspend: true): Exclude<R, undefined>;
253
- declare function get<R, T>(compute: (property: string) => (this: T, state: T) => R, suspend?: boolean): R;
250
+ declare function get<R, T>(compute: (property: string, on: T) => (this: T, state: T) => R, suspend: true): Exclude<R, undefined>;
251
+ declare function get<R, T>(compute: (property: string, on: T) => (this: T, state: T) => R, suspend?: boolean): R;
254
252
  /**
255
- * Set property with an async function.
256
- *
257
- * Property cannot be accessed until factory resolves, yeilding a result.
258
- * If accessed while processing, React Suspense will be thrown.
259
- *
260
- * - `required: true` (default) -
261
- * Run factory immediately upon creation of model instance.
262
- * - `required: false` -
263
- * Run factory only if/when accessed.
264
- * Value will always throw suspense at least once - use with caution.
265
- *
266
- * @param factory - Callback run to derrive property value.
267
- * @param required - (default: true) Run factory immediately on creation, otherwise on access.
268
- */
269
- declare function get<T>(factory: get.Factory2<Promise<T>>, required: false): T | undefined;
270
- declare function get<T, S>(factory: get.Factory2<Promise<T>, S>, required: false): T | undefined;
271
- declare function get<T>(factory: get.Factory2<Promise<T>>, required?: boolean): T;
272
- declare function get<T, S>(factory: get.Factory2<Promise<T>, S>, required?: boolean): T;
253
+ * Set property with an async function.
254
+ *
255
+ * Property cannot be accessed until factory resolves, yeilding a result.
256
+ * If accessed while processing, React Suspense will be thrown.
257
+ *
258
+ * - `required: true` (default) -
259
+ * Run factory immediately upon creation of model instance.
260
+ * - `required: false` -
261
+ * Run factory only if/when accessed.
262
+ * Value will always throw suspense at least once - use with caution.
263
+ *
264
+ * @param factory - Callback run to derrive property value.
265
+ * @param required - (default: true) Run factory immediately on creation, otherwise on access.
266
+ */
267
+ declare function get<T>(factory: get.Factory<Promise<T>>, required: false): T | undefined;
268
+ declare function get<T, S>(factory: get.Factory<Promise<T>, S>, required: false): T | undefined;
269
+ declare function get<T>(factory: get.Factory<Promise<T>>, required?: boolean): T;
270
+ declare function get<T, S>(factory: get.Factory<Promise<T>, S>, required?: boolean): T;
273
271
  /**
274
- * Set property with a factory function.
275
- *
276
- * - `required: true` (default) -
277
- * Run factory immediately upon creation of model instance.
278
- * - `required: false` -
279
- * Run factory only if/when accessed.
280
- * Value will always throw suspense at least once - use with caution.
281
- *
282
- * @param factory - Callback run to derrive property value.
283
- * @param required - (default: true) Run factory immediately on creation, otherwise on access.
284
- */
285
- declare function get<T>(factory: get.Factory2<T>, required: false): T | undefined;
286
- declare function get<T, S>(factory: get.Factory2<T, S>, required: false): T | undefined;
287
- declare function get<T>(factory: get.Factory2<T>, required?: boolean): T;
288
- declare function get<T, S>(factory: get.Factory2<T, S>, required?: boolean): T;
272
+ * Set property with a factory function.
273
+ *
274
+ * - `required: true` (default) -
275
+ * Run factory immediately upon creation of model instance.
276
+ * - `required: false` -
277
+ * Run factory only if/when accessed.
278
+ * Value will always throw suspense at least once - use with caution.
279
+ *
280
+ * @param factory - Callback run to derrive property value.
281
+ * @param required - (default: true) Run factory immediately on creation, otherwise on access.
282
+ */
283
+ declare function get<T>(factory: get.Factory<T>, required: false): T | undefined;
284
+ declare function get<T, S>(factory: get.Factory<T, S>, required: false): T | undefined;
285
+ declare function get<T>(factory: get.Factory<T>, required?: boolean): T;
286
+ declare function get<T, S>(factory: get.Factory<T, S>, required?: boolean): T;
289
287
  /**
290
288
  * Assign a property with result of a promise.
291
289
  */
package/lib/index.esm.js CHANGED
@@ -17,11 +17,11 @@ function issues(register) {
17
17
  return Library;
18
18
  }
19
19
 
20
- const Oops$b = issues({
20
+ const Oops$c = issues({
21
21
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
22
22
  });
23
23
  function suspend(source, key) {
24
- const error = Oops$b.NotReady(source.subject, key);
24
+ const error = Oops$c.NotReady(source.subject, key);
25
25
  const promise = new Promise(resolve => {
26
26
  const release = source.addListener(forKey => {
27
27
  if (forKey == key)
@@ -61,106 +61,12 @@ function mayRetry(fn) {
61
61
  return compute();
62
62
  }
63
63
 
64
- const Oops$a = issues({
65
- BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
66
- PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
67
- Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
68
- FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
69
- NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
70
- ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`
64
+ const Oops$b = issues({
65
+ Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
71
66
  });
72
67
  const INFO = new WeakMap();
73
68
  const KEYS = new WeakMap();
74
69
  const ORDER = new WeakMap();
75
- function get(arg0, arg1, arg2) {
76
- return apply(function get(key) {
77
- const { subject } = this;
78
- const computeRequired = arg1 === true || arg2 === true;
79
- const factoryRequired = arg1 !== false && arg2 !== false;
80
- let getter;
81
- // Easy mistake, using a peer, will always be unresolved.
82
- if (typeof arg0 == "symbol")
83
- throw Oops$a.PeerNotAllowed(subject, key);
84
- if (typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
85
- throw Oops$a.BadSource(subject, key, arg0);
86
- this.state.set(key, undefined);
87
- const init = () => {
88
- let source = this;
89
- let setter;
90
- if (typeof arg0 == "function") {
91
- const result = mayRetry(() => arg0.call(subject, key, subject));
92
- if (typeof result == "function")
93
- setter = result;
94
- else {
95
- getter = factoryMode(this, result, key, factoryRequired);
96
- return;
97
- }
98
- }
99
- else if (arg0 instanceof Promise) {
100
- getter = factoryMode(this, arg0, key, factoryRequired);
101
- return;
102
- }
103
- else if (typeof arg1 == "function") {
104
- // replace source controller in-case it is different
105
- source = ensure(arg0);
106
- setter = arg1;
107
- }
108
- else
109
- throw new Error(`Factory argument cannot be ${arg1}`);
110
- getter = computeMode(this, source, setter, key, computeRequired);
111
- };
112
- if (typeof arg0 == "function" && factoryRequired)
113
- try {
114
- init();
115
- }
116
- catch (err) {
117
- Oops$a.ComputeFailed(subject, key).warn();
118
- throw err;
119
- }
120
- return () => {
121
- if (!getter)
122
- init();
123
- return getter();
124
- };
125
- });
126
- }
127
- function factoryMode(self, output, key, required) {
128
- const { subject, state } = self;
129
- let pending;
130
- let error;
131
- if (output instanceof Promise) {
132
- state.set(key, undefined);
133
- pending = output
134
- .catch(err => error = err)
135
- .then(val => {
136
- state.set(key, val);
137
- return val;
138
- })
139
- .finally(() => {
140
- pending = undefined;
141
- self.update(key);
142
- });
143
- }
144
- state.set(key, output);
145
- const suspend = () => {
146
- if (required === false)
147
- return undefined;
148
- const issue = Oops$a.NotReady(subject, key);
149
- Object.assign(pending, {
150
- message: issue.message,
151
- stack: issue.stack
152
- });
153
- throw pending;
154
- };
155
- return () => {
156
- if (error)
157
- throw error;
158
- if (pending)
159
- return suspend();
160
- if (state.has(key))
161
- return state.get(key);
162
- };
163
- }
164
70
  function computeMode(self, source, setter, key, required) {
165
71
  const { subject, state } = self;
166
72
  let sub;
@@ -172,7 +78,7 @@ function computeMode(self, source, setter, key, required) {
172
78
  return setter.call(sub.proxy, sub.proxy);
173
79
  }
174
80
  catch (err) {
175
- Oops$a.Failed(subject, key, initial).warn();
81
+ Oops$b.Failed(subject, key, initial).warn();
176
82
  throw err;
177
83
  }
178
84
  };
@@ -241,7 +147,7 @@ function flush(control) {
241
147
  KEYS.delete(control);
242
148
  }
243
149
 
244
- const Oops$9 = issues({
150
+ const Oops$a = issues({
245
151
  BadCallback: () => `Callback for effect-callback may only return a function.`
246
152
  });
247
153
  const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
@@ -254,7 +160,7 @@ function createEffect(callback) {
254
160
  if (unSet instanceof Promise)
255
161
  unSet = undefined;
256
162
  if (unSet && typeof unSet !== "function")
257
- throw Oops$9.BadCallback();
163
+ throw Oops$a.BadCallback();
258
164
  };
259
165
  }
260
166
  function createValueEffect(callback) {
@@ -270,11 +176,11 @@ function createValueEffect(callback) {
270
176
  if (typeof out == "function")
271
177
  unSet = out;
272
178
  else
273
- throw Oops$9.BadCallback();
179
+ throw Oops$a.BadCallback();
274
180
  };
275
181
  }
276
182
 
277
- const Oops$8 = issues({
183
+ const Oops$9 = issues({
278
184
  Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
279
185
  StrictUpdate: () => `Strict update() did not find pending updates.`,
280
186
  NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
@@ -357,7 +263,7 @@ class Model {
357
263
  const invoke = (key) => {
358
264
  if (!key) {
359
265
  clear();
360
- reject(Oops$8.Timeout(select, typeof argument == "number"
266
+ reject(Oops$9.Timeout(select, typeof argument == "number"
361
267
  ? `${argument}ms`
362
268
  : `lifetime of ${this}`));
363
269
  }
@@ -444,11 +350,11 @@ class Model {
444
350
  arg = undefined;
445
351
  }
446
352
  if (!frame.size && arg === true)
447
- return Promise.reject(Oops$8.StrictUpdate());
353
+ return Promise.reject(Oops$9.StrictUpdate());
448
354
  return {
449
355
  then: (callback) => {
450
356
  if (!callback)
451
- throw Oops$8.NoChaining();
357
+ throw Oops$9.NoChaining();
452
358
  if (frame.size || arg !== false)
453
359
  waiting.add(() => {
454
360
  callback(getUpdate(this));
@@ -777,7 +683,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
777
683
  });
778
684
  }
779
685
 
780
- const Oops$7 = issues({
686
+ const Oops$8 = issues({
781
687
  DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
782
688
  });
783
689
  function act(task) {
@@ -785,7 +691,7 @@ function act(task) {
785
691
  let pending = false;
786
692
  const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
787
693
  if (pending)
788
- return Promise.reject(Oops$7.DuplicatePending(key));
694
+ return Promise.reject(Oops$8.DuplicatePending(key));
789
695
  pending = true;
790
696
  this.update(key);
791
697
  try {
@@ -807,6 +713,106 @@ function act(task) {
807
713
  });
808
714
  }
809
715
 
716
+ function factoryMode(self, output, key, required) {
717
+ const { subject, state } = self;
718
+ let pending;
719
+ let error;
720
+ if (output instanceof Promise) {
721
+ state.set(key, undefined);
722
+ pending = output
723
+ .catch(err => error = err)
724
+ .then(val => {
725
+ state.set(key, val);
726
+ return val;
727
+ })
728
+ .finally(() => {
729
+ pending = undefined;
730
+ self.update(key);
731
+ });
732
+ }
733
+ state.set(key, output);
734
+ const suspend = () => {
735
+ if (required === false)
736
+ return undefined;
737
+ const issue = Oops$7.NotReady(subject, key);
738
+ Object.assign(pending, {
739
+ message: issue.message,
740
+ stack: issue.stack
741
+ });
742
+ throw pending;
743
+ };
744
+ return () => {
745
+ if (error)
746
+ throw error;
747
+ if (pending)
748
+ return suspend();
749
+ if (state.has(key))
750
+ return state.get(key);
751
+ };
752
+ }
753
+
754
+ const Oops$7 = issues({
755
+ // BadSource: (model, property, got) =>
756
+ // `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
757
+ PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
758
+ ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
759
+ NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
760
+ FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
761
+ Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
762
+ });
763
+ function get(arg0, arg1, arg2) {
764
+ return apply(function get(key) {
765
+ const { subject } = this;
766
+ const computeRequired = arg1 === true || arg2 === true;
767
+ const factoryRequired = arg1 !== false && arg2 !== false;
768
+ let getter;
769
+ // Easy mistake, using a peer, will always be unresolved.
770
+ if (typeof arg0 == "symbol")
771
+ throw Oops$7.PeerNotAllowed(subject, key);
772
+ // if(typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
773
+ // throw Oops.BadSource(subject, key, arg0);
774
+ this.state.set(key, undefined);
775
+ const init = () => {
776
+ let source = this;
777
+ let setter;
778
+ if (typeof arg0 == "function") {
779
+ const result = mayRetry(() => arg0.call(subject, key, subject));
780
+ if (typeof result == "function")
781
+ setter = result;
782
+ else {
783
+ getter = factoryMode(this, result, key, factoryRequired);
784
+ return;
785
+ }
786
+ }
787
+ else if (arg0 instanceof Promise) {
788
+ getter = factoryMode(this, arg0, key, factoryRequired);
789
+ return;
790
+ }
791
+ else if (typeof arg1 == "function") {
792
+ // replace source controller in-case it is different
793
+ source = ensure(arg0);
794
+ setter = arg1;
795
+ }
796
+ else
797
+ throw new Error(`Factory argument cannot be ${arg1}`);
798
+ getter = computeMode(this, source, setter, key, computeRequired);
799
+ };
800
+ if (typeof arg0 == "function" && factoryRequired)
801
+ try {
802
+ init();
803
+ }
804
+ catch (err) {
805
+ Oops$7.ComputeFailed(subject, key).warn();
806
+ throw err;
807
+ }
808
+ return () => {
809
+ if (!getter)
810
+ init();
811
+ return getter();
812
+ };
813
+ });
814
+ }
815
+
810
816
  function ref(callback) {
811
817
  return apply(function ref(key) {
812
818
  const value = this.ref(key, callback && createValueEffect(callback));
@@ -993,9 +999,11 @@ function use$1(input, argument) {
993
999
  let pending;
994
1000
  let error;
995
1001
  let get = (_local) => state.get(key);
996
- if (typeof input === "function")
997
- input = /^[A-Z]/.test(input.name)
998
- ? new input() : input;
1002
+ if (typeof input === "function") {
1003
+ if ("prototype" in input &&
1004
+ input === input.prototype.constructor)
1005
+ input = new input();
1006
+ }
999
1007
  else if (input && typeof input !== "object")
1000
1008
  throw Oops$6.BadArgument(typeof input);
1001
1009
  if (input instanceof Map || input instanceof Set)