@expressive/mvc 0.39.0 → 0.40.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/dist/index.d.ts CHANGED
@@ -64,6 +64,13 @@ declare namespace Model {
64
64
  * Optional returned callback will run when once upon first access.
65
65
  */
66
66
  type Instruction<T = any, M extends Model = any> = (this: M, key: Model.Field<M> & string, thisArg: M, state: Model.State<M>) => Instruction.Descriptor<T> | Instruction.Getter<T> | void;
67
+ /**
68
+ * Model constructor callback - is called when Model finishes intializing.
69
+ * Returned function will call when model is destroyed.
70
+ */
71
+ type Callback = (() => void | (() => void));
72
+ /** Model constructor argument */
73
+ type Argument = string | Callback;
67
74
  }
68
75
  interface Model {
69
76
  /**
@@ -73,7 +80,7 @@ interface Model {
73
80
  is: this;
74
81
  }
75
82
  declare class Model {
76
- constructor(arg?: string | (() => void | (() => void)));
83
+ constructor(arg?: Model.Argument);
77
84
  /** Pull current values from state. Flattens all models and exotic values recursively. */
78
85
  get(): Model.State<this>;
79
86
  /**
@@ -187,8 +194,8 @@ declare class Model {
187
194
  declare function add<T = any>(instruction: Model.Instruction): T;
188
195
 
189
196
  declare namespace get {
190
- type Function<T, S = any> = (this: S, on: S) => T;
191
- type Factory<R, T> = (this: T, property: string, on: T) => Function<R, T>;
197
+ type Function<T, S = any> = (on: S, key: string) => T;
198
+ type Factory<T, S = any> = (this: S, key: string, thisArg: S) => T;
192
199
  type Source<T extends Model = Model> = (resolve: (x: T) => void) => void;
193
200
  }
194
201
  /**
@@ -216,20 +223,22 @@ declare function get<T extends Model>(Type: Model.Type<T>, required?: false): T
216
223
  * @param source - Type of Model to fetch for computation.
217
224
  * @param compute - Compute function. Will update automatically as input values change.
218
225
  */
219
- declare function get<R, T extends Model>(Type: Model.Type<T>, compute: (this: T, on: T) => R): R;
226
+ declare function get<R, T extends Model>(Type: Model.Type<T>, compute: get.Function<R, T>): R;
220
227
  /**
221
228
  * Implement a computed value; output will be generated by provided function.
222
229
  *
223
230
  * @param source - Source model from which computed value will be a subscriber.
224
231
  * @param compute - Compute function. Bound to a subscriber-proxy of source, returns output value. Will update automatically as input values change.
225
232
  */
226
- declare function get<R, T extends Model>(source: T, compute: (this: T, on: T) => R): R;
233
+ declare function get<R, T extends Model>(source: T, compute: get.Function<R, T>): R;
227
234
  /**
228
235
  * Implement a computed value; output is returned by function from provided factory.
229
236
  *
237
+ * Factory is bound to owner of property.
238
+ *
230
239
  * @param compute - Factory function to generate a getter to subscribe dependancies.
231
240
  */
232
- declare function get<R, T>(compute: (property: string, on: T) => (this: T, state: T) => R): R;
241
+ declare function get<R, T>(compute: get.Factory<R, T>): R;
233
242
 
234
243
  declare namespace ref {
235
244
  type Callback<T> = (argument: T) => ((next: T | null) => void) | Promise<void> | void | boolean;
package/dist/index.js CHANGED
@@ -154,6 +154,7 @@ var STATE = /* @__PURE__ */ new WeakMap();
154
154
  var NOTIFY = /* @__PURE__ */ new WeakMap();
155
155
  var PENDING2 = /* @__PURE__ */ new WeakMap();
156
156
  var PARENT = /* @__PURE__ */ new WeakMap();
157
+ var METHOD = /* @__PURE__ */ new WeakMap();
157
158
  var define = Object.defineProperty;
158
159
  var Model = class _Model {
159
160
  constructor(arg) {
@@ -166,6 +167,22 @@ var Model = class _Model {
166
167
  new Set(NOTIFY.get(Type)).forEach((x) => addListener(this, x));
167
168
  if (Type === _Model)
168
169
  break;
170
+ const desc = Object.getOwnPropertyDescriptors(Type.prototype);
171
+ for (const key in desc) {
172
+ let { value } = desc[key];
173
+ if (typeof value == "function" && key !== "constructor")
174
+ Object.defineProperty(Type.prototype, key, {
175
+ get() {
176
+ const method = value.bind(this.is);
177
+ METHOD.set(method, value);
178
+ define(this.is, key, {
179
+ value: method,
180
+ configurable: false
181
+ });
182
+ return method;
183
+ }
184
+ });
185
+ }
169
186
  Type = Object.getPrototypeOf(Type);
170
187
  }
171
188
  addListener(this, () => {
@@ -442,8 +459,10 @@ function get(arg0, arg1) {
442
459
  from = hasParent;
443
460
  else
444
461
  throw new Error(`New ${from} created as child of ${hasParent}, but must be instanceof ${arg0}.`);
445
- } else if (typeof arg0 == "function")
446
- arg1 = arg0.call(from, key, from);
462
+ } else if (typeof arg0 == "function") {
463
+ const fn = METHOD.get(arg0) || arg0;
464
+ arg1 = (p, k) => fn.call(p, k, p);
465
+ }
447
466
  if (typeof arg1 == "function")
448
467
  return compute(subject, key, source, arg1);
449
468
  source((got) => subject.set(key, got));
@@ -473,7 +492,7 @@ function compute(subject, key, source, setter) {
473
492
  function compute2(initial) {
474
493
  let next;
475
494
  try {
476
- next = setter.call(proxy, proxy);
495
+ next = setter.call(proxy, proxy, key);
477
496
  } catch (err) {
478
497
  console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key}.`);
479
498
  if (initial)
package/dist/index.mjs CHANGED
@@ -120,6 +120,7 @@ var STATE = /* @__PURE__ */ new WeakMap();
120
120
  var NOTIFY = /* @__PURE__ */ new WeakMap();
121
121
  var PENDING2 = /* @__PURE__ */ new WeakMap();
122
122
  var PARENT = /* @__PURE__ */ new WeakMap();
123
+ var METHOD = /* @__PURE__ */ new WeakMap();
123
124
  var define = Object.defineProperty;
124
125
  var Model = class _Model {
125
126
  constructor(arg) {
@@ -132,6 +133,22 @@ var Model = class _Model {
132
133
  new Set(NOTIFY.get(Type)).forEach((x) => addListener(this, x));
133
134
  if (Type === _Model)
134
135
  break;
136
+ const desc = Object.getOwnPropertyDescriptors(Type.prototype);
137
+ for (const key in desc) {
138
+ let { value } = desc[key];
139
+ if (typeof value == "function" && key !== "constructor")
140
+ Object.defineProperty(Type.prototype, key, {
141
+ get() {
142
+ const method = value.bind(this.is);
143
+ METHOD.set(method, value);
144
+ define(this.is, key, {
145
+ value: method,
146
+ configurable: false
147
+ });
148
+ return method;
149
+ }
150
+ });
151
+ }
135
152
  Type = Object.getPrototypeOf(Type);
136
153
  }
137
154
  addListener(this, () => {
@@ -408,8 +425,10 @@ function get(arg0, arg1) {
408
425
  from = hasParent;
409
426
  else
410
427
  throw new Error(`New ${from} created as child of ${hasParent}, but must be instanceof ${arg0}.`);
411
- } else if (typeof arg0 == "function")
412
- arg1 = arg0.call(from, key, from);
428
+ } else if (typeof arg0 == "function") {
429
+ const fn = METHOD.get(arg0) || arg0;
430
+ arg1 = (p, k) => fn.call(p, k, p);
431
+ }
413
432
  if (typeof arg1 == "function")
414
433
  return compute(subject, key, source, arg1);
415
434
  source((got) => subject.set(key, got));
@@ -439,7 +458,7 @@ function compute(subject, key, source, setter) {
439
458
  function compute2(initial) {
440
459
  let next;
441
460
  try {
442
- next = setter.call(proxy, proxy);
461
+ next = setter.call(proxy, proxy, key);
443
462
  } catch (err) {
444
463
  console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key}.`);
445
464
  if (initial)
package/package.json CHANGED
@@ -28,6 +28,6 @@
28
28
  "prebuild": "rm -rf dist",
29
29
  "preversion": "npm run test && npm run build"
30
30
  },
31
- "version": "0.39.0",
32
- "gitHead": "40cda872145802a7e87964695840d7ee27053844"
31
+ "version": "0.40.0",
32
+ "gitHead": "1eb515499dc2d6571d0cc97406192ce8eb0714d2"
33
33
  }