@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 +6 -5
- package/dist/index.js +37 -25
- package/dist/index.mjs +37 -25
- package/package.json +2 -2
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> |
|
|
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
|
|
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:
|
|
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
|
|
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 &&
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
use2.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
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
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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
|
-
|
|
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
|
|
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 &&
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
use2.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
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
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
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
|
|
763
|
+
I = new input();
|
|
752
764
|
} else {
|
|
753
765
|
I = input;
|
|
754
766
|
T = I.constructor;
|
package/package.json
CHANGED