@expressive/mvc 0.44.0 → 0.46.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
@@ -1,3 +1,4 @@
1
+ type MaybeAsync<T> = T | Promise<T>;
1
2
  declare namespace Model {
2
3
  /** Any type of Model, using own class constructor as its identifier. */
3
4
  type Type<T extends Model = Model> = (abstract new (...args: any[]) => T) & typeof Model;
@@ -5,18 +6,18 @@ declare namespace Model {
5
6
  * Model constructor callback - is called when Model finishes intializing.
6
7
  * Returned function will call when model is destroyed.
7
8
  */
8
- type Callback<T extends Model = Model> = (this: T, thisArg: T) => (() => void) | Assign<T> | Promise<void> | void;
9
+ type Callback<T extends Model = Model> = (this: T, thisArg: T) => MaybeAsync<(() => void) | Assign<T> | void>;
9
10
  /** Model constructor argument */
10
- type Argument<T extends Model = Model> = string | Callback<T> | Assign<T> | void;
11
+ type Argument<T extends Model = Model> = string | Assign<T> | Callback<T> | Promise<Assign<T> | (() => void) | void> | void;
11
12
  /** Model constructor arguments */
12
13
  type Args<T extends Model = any> = Argument<T>[];
13
14
  /** Subset of `keyof T` which are not methods or defined by base Model U. **/
14
15
  type Field<T> = Exclude<keyof T, keyof Model>;
15
16
  /** Any valid key for controller, including but not limited to Field<T>. */
16
17
  type Event<T> = Field<T> | (string & {}) | number | symbol;
17
- /** Object overlay which may be used to override values and methods while creating model. */
18
+ /** Object overlay which may be used to override values and methods on a model. */
18
19
  type Assign<T> = {
19
- [K in Exclude<keyof T, keyof Model>]?: T[K] extends (...args: any[]) => infer R ? (this: T, ...args: Parameters<T[K]>) => ReturnType<T[K]> : T[K];
20
+ [K in Exclude<keyof T, keyof Model>]?: T[K] extends (...args: infer A) => infer R ? (this: T, ...args: A) => R : T[K];
20
21
  } & Record<string, unknown>;
21
22
  /** Export/Import compatible value for a given property in a Model. */
22
23
  type Export<R> = R extends {
@@ -379,7 +380,7 @@ declare class Context {
379
380
  key(T: Model.Type, upstream?: boolean): keyof this;
380
381
  has(model: Model): (() => void) | undefined;
381
382
  get<T extends Model>(Type: Model.Type<T>): T | undefined;
382
- include(inputs: Context.Input): Map<Model, boolean>;
383
+ include(inputs: Context.Input, forEach?: (added: Model, explicit: boolean) => void): void;
383
384
  put<T extends Model>(T: Model.Type<T>, I: T | ((model: T) => void), implicit?: boolean, writable?: boolean): void;
384
385
  add<T extends Model>(input: T | Model.Type<T>, implicit?: boolean): T;
385
386
  push(inputs?: Context.Input): this;
package/dist/index.js CHANGED
@@ -66,13 +66,16 @@ function watch(from, key, value) {
66
66
  var PENDING = /* @__PURE__ */ new WeakMap();
67
67
  function event(source, key) {
68
68
  const subs = LISTENER.get(source);
69
+ const ready = !subs.has(onReady);
70
+ if (key === true && ready)
71
+ return;
69
72
  let pending = PENDING.get(source);
70
73
  if (pending) {
71
74
  pending.add(key);
72
75
  return;
73
76
  }
74
77
  PENDING.set(source, pending = new Set(
75
- key !== true && subs.has(onReady) ? [true, key] : [key]
78
+ key !== true && ready ? [key] : [true, key]
76
79
  ));
77
80
  pending.forEach((key2) => {
78
81
  pending.delete(key2);
@@ -174,19 +177,23 @@ var Model = class _Model {
174
177
  Type = Object.getPrototypeOf(Type);
175
178
  }
176
179
  addListener(this, () => {
177
- const cleanup = /* @__PURE__ */ new Set();
178
- for (const arg of args) {
179
- const use2 = typeof arg == "function" ? arg.call(this, this) : arg;
180
- if (use2 instanceof Promise)
181
- use2.catch((err) => {
182
- console.error(`Async error in constructor for ${this}:`);
183
- console.error(err);
184
- });
185
- else if (typeof use2 == "object")
186
- assign(this, use2);
187
- else if (typeof use2 == "function")
188
- cleanup.add(use2);
189
- }
180
+ let done;
181
+ (async () => {
182
+ const cleanup = /* @__PURE__ */ new Set();
183
+ for (const arg of args) {
184
+ let use2 = typeof arg == "function" ? arg.call(this, this) : arg;
185
+ if (use2 instanceof Promise)
186
+ use2 = await use2.catch((err) => {
187
+ console.error(`Async error in constructor for ${this}:`);
188
+ console.error(err);
189
+ });
190
+ if (typeof use2 == "object")
191
+ assign(this, use2);
192
+ else if (typeof use2 == "function")
193
+ cleanup.add(use2);
194
+ }
195
+ done = cleanup;
196
+ })();
190
197
  for (const key in this) {
191
198
  const desc = Object.getOwnPropertyDescriptor(this, key);
192
199
  if ("value" in desc) {
@@ -201,10 +208,12 @@ var Model = class _Model {
201
208
  }
202
209
  }
203
210
  addListener(this, () => {
211
+ if (!done)
212
+ throw new Error(`Tried to destroy ${this} but not fully initialized.`);
204
213
  for (const [_, value] of this)
205
214
  if (value instanceof _Model && PARENT.get(value) === this)
206
215
  value.set(null);
207
- cleanup.forEach((x) => x());
216
+ done.forEach((x) => x());
208
217
  Object.freeze(state);
209
218
  }, null);
210
219
  return null;
@@ -260,11 +269,12 @@ var Model = class _Model {
260
269
  return event(this, null);
261
270
  if (typeof arg1 == "object")
262
271
  assign(self, arg1);
263
- else if (arg1 !== void 0)
264
- if (1 in arguments)
265
- update(self, arg1, arg2, arg3);
266
- else
267
- push(self, arg1);
272
+ else if (arg1 == void 0)
273
+ event(this, true);
274
+ else if (1 in arguments)
275
+ update(self, arg1, arg2, arg3);
276
+ else
277
+ push(self, arg1);
268
278
  if (PENDING2.has(self))
269
279
  return {
270
280
  then: (res) => new Promise((res2) => {
@@ -726,7 +736,7 @@ var Context = class {
726
736
  throw new Error(`Did find ${Type} in context, but multiple were defined.`);
727
737
  return result;
728
738
  }
729
- include(inputs) {
739
+ include(inputs, forEach) {
730
740
  const init = /* @__PURE__ */ new Map();
731
741
  if (typeof inputs == "function" || inputs instanceof Model)
732
742
  inputs = { [0]: inputs };
@@ -746,10 +756,13 @@ var Context = class {
746
756
  } else if (exists !== input) {
747
757
  this.pop();
748
758
  this.id = uid();
749
- return this.include(inputs);
759
+ this.include(inputs);
750
760
  }
751
761
  }
752
- for (const [model] of init) {
762
+ for (const [model, explicit] of init) {
763
+ if (forEach)
764
+ forEach(model, explicit);
765
+ model.set();
753
766
  this.has(model);
754
767
  const expects = Expects.get(model);
755
768
  if (expects)
@@ -761,7 +774,6 @@ var Context = class {
761
774
  init.set(value, false);
762
775
  }
763
776
  }
764
- return init;
765
777
  }
766
778
  put(T, I, implicit, writable) {
767
779
  do {
@@ -782,7 +794,7 @@ var Context = class {
782
794
  let I;
783
795
  if (typeof input == "function") {
784
796
  T = input;
785
- I = input.new();
797
+ I = new input();
786
798
  } else {
787
799
  I = input;
788
800
  T = I.constructor;
package/dist/index.mjs CHANGED
@@ -32,13 +32,16 @@ function watch(from, key, value) {
32
32
  var PENDING = /* @__PURE__ */ new WeakMap();
33
33
  function event(source, key) {
34
34
  const subs = LISTENER.get(source);
35
+ const ready = !subs.has(onReady);
36
+ if (key === true && ready)
37
+ return;
35
38
  let pending = PENDING.get(source);
36
39
  if (pending) {
37
40
  pending.add(key);
38
41
  return;
39
42
  }
40
43
  PENDING.set(source, pending = new Set(
41
- key !== true && subs.has(onReady) ? [true, key] : [key]
44
+ key !== true && ready ? [key] : [true, key]
42
45
  ));
43
46
  pending.forEach((key2) => {
44
47
  pending.delete(key2);
@@ -140,19 +143,23 @@ var Model = class _Model {
140
143
  Type = Object.getPrototypeOf(Type);
141
144
  }
142
145
  addListener(this, () => {
143
- const cleanup = /* @__PURE__ */ new Set();
144
- for (const arg of args) {
145
- const use2 = typeof arg == "function" ? arg.call(this, this) : arg;
146
- if (use2 instanceof Promise)
147
- use2.catch((err) => {
148
- console.error(`Async error in constructor for ${this}:`);
149
- console.error(err);
150
- });
151
- else if (typeof use2 == "object")
152
- assign(this, use2);
153
- else if (typeof use2 == "function")
154
- cleanup.add(use2);
155
- }
146
+ let done;
147
+ (async () => {
148
+ const cleanup = /* @__PURE__ */ new Set();
149
+ for (const arg of args) {
150
+ let use2 = typeof arg == "function" ? arg.call(this, this) : arg;
151
+ if (use2 instanceof Promise)
152
+ use2 = await use2.catch((err) => {
153
+ console.error(`Async error in constructor for ${this}:`);
154
+ console.error(err);
155
+ });
156
+ if (typeof use2 == "object")
157
+ assign(this, use2);
158
+ else if (typeof use2 == "function")
159
+ cleanup.add(use2);
160
+ }
161
+ done = cleanup;
162
+ })();
156
163
  for (const key in this) {
157
164
  const desc = Object.getOwnPropertyDescriptor(this, key);
158
165
  if ("value" in desc) {
@@ -167,10 +174,12 @@ var Model = class _Model {
167
174
  }
168
175
  }
169
176
  addListener(this, () => {
177
+ if (!done)
178
+ throw new Error(`Tried to destroy ${this} but not fully initialized.`);
170
179
  for (const [_, value] of this)
171
180
  if (value instanceof _Model && PARENT.get(value) === this)
172
181
  value.set(null);
173
- cleanup.forEach((x) => x());
182
+ done.forEach((x) => x());
174
183
  Object.freeze(state);
175
184
  }, null);
176
185
  return null;
@@ -226,11 +235,12 @@ var Model = class _Model {
226
235
  return event(this, null);
227
236
  if (typeof arg1 == "object")
228
237
  assign(self, arg1);
229
- else if (arg1 !== void 0)
230
- if (1 in arguments)
231
- update(self, arg1, arg2, arg3);
232
- else
233
- push(self, arg1);
238
+ else if (arg1 == void 0)
239
+ event(this, true);
240
+ else if (1 in arguments)
241
+ update(self, arg1, arg2, arg3);
242
+ else
243
+ push(self, arg1);
234
244
  if (PENDING2.has(self))
235
245
  return {
236
246
  then: (res) => new Promise((res2) => {
@@ -692,7 +702,7 @@ var Context = class {
692
702
  throw new Error(`Did find ${Type} in context, but multiple were defined.`);
693
703
  return result;
694
704
  }
695
- include(inputs) {
705
+ include(inputs, forEach) {
696
706
  const init = /* @__PURE__ */ new Map();
697
707
  if (typeof inputs == "function" || inputs instanceof Model)
698
708
  inputs = { [0]: inputs };
@@ -712,10 +722,13 @@ var Context = class {
712
722
  } else if (exists !== input) {
713
723
  this.pop();
714
724
  this.id = uid();
715
- return this.include(inputs);
725
+ this.include(inputs);
716
726
  }
717
727
  }
718
- for (const [model] of init) {
728
+ for (const [model, explicit] of init) {
729
+ if (forEach)
730
+ forEach(model, explicit);
731
+ model.set();
719
732
  this.has(model);
720
733
  const expects = Expects.get(model);
721
734
  if (expects)
@@ -727,7 +740,6 @@ var Context = class {
727
740
  init.set(value, false);
728
741
  }
729
742
  }
730
- return init;
731
743
  }
732
744
  put(T, I, implicit, writable) {
733
745
  do {
@@ -748,7 +760,7 @@ var Context = class {
748
760
  let I;
749
761
  if (typeof input == "function") {
750
762
  T = input;
751
- I = input.new();
763
+ I = new input();
752
764
  } else {
753
765
  I = input;
754
766
  T = I.constructor;
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.44.0",
32
- "gitHead": "b9a450ae7d25a8845d344faed39495bbdfc69b47"
31
+ "version": "0.46.0",
32
+ "gitHead": "22ffbbadad0ab45f73c71e178183941e78ed2a56"
33
33
  }