@expressive/mvc 0.28.0 → 0.29.1
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 +19 -7
- package/lib/index.esm.js +42 -32
- package/lib/index.js +42 -32
- package/package.json +2 -2
package/lib/index.d.ts
CHANGED
|
@@ -58,13 +58,15 @@ declare global {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
type OnValue<T, P extends Model.Key<T>> = (this: T, value: T[P], updated: Model.Event<T>[]) => void;
|
|
62
|
+
type OnValues<T, P extends Model.Key<T>> = (this: T, value: Model.Export<T, P>, updated: Model.Event<T>[]) => void;
|
|
61
63
|
interface Observable {
|
|
62
64
|
get(): Model.Export<this>;
|
|
63
65
|
get(effect: Model.Effect<this>): Callback;
|
|
64
66
|
get<P extends Model.Key<this>>(select: P): this[P];
|
|
65
|
-
get<P extends Model.Key<this>>(select:
|
|
66
|
-
get<P extends Model.Key<this>>(select: P
|
|
67
|
-
get<P extends Model.Key<this>>(select:
|
|
67
|
+
get<P extends Model.Key<this>>(select: P, onUpdate: OnValue<this, P>, once?: boolean): Callback;
|
|
68
|
+
get<P extends Model.Key<this>>(select: P[]): Model.Export<this, P>;
|
|
69
|
+
get<P extends Model.Key<this>>(select: P[], onUpdate: OnValues<this, P>, once?: boolean): Callback;
|
|
68
70
|
set(): Promise<Model.Event<this>[]>;
|
|
69
71
|
set(timeout: number): Promise<Model.Event<this>[] | false>;
|
|
70
72
|
set<T extends Model.Values<this>>(source: T, only?: (keyof T)[]): Promise<Model.Event<T>[] | false>;
|
|
@@ -93,7 +95,7 @@ declare namespace Model {
|
|
|
93
95
|
/** Including but not limited to `keyof T` which are not methods or defined by base Model. */
|
|
94
96
|
type Event<T> = Key<T> | (string & {});
|
|
95
97
|
/** Actual value stored in state. */
|
|
96
|
-
type Value<R> = R extends Ref<infer T> ? T : R;
|
|
98
|
+
type Value<R> = R extends Ref<infer T> ? T : R extends Observable ? Export<R> : R;
|
|
97
99
|
/** Object comperable to data found in T. */
|
|
98
100
|
type Values<T> = {
|
|
99
101
|
[P in Key<T>]?: Value<T[P]>;
|
|
@@ -137,7 +139,7 @@ declare class Model {
|
|
|
137
139
|
*
|
|
138
140
|
* Will determine if provided class is a subtype of this one.
|
|
139
141
|
*/
|
|
140
|
-
static
|
|
142
|
+
static is<T extends Model.Type>(this: T, maybe: any): maybe is T;
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
declare namespace get {
|
|
@@ -174,9 +176,9 @@ declare function get<R, T>(compute: (property: string, on: T) => (this: T, state
|
|
|
174
176
|
declare function get<R, T>(compute: (property: string, on: T) => (this: T, state: T) => R): R;
|
|
175
177
|
|
|
176
178
|
declare namespace ref {
|
|
177
|
-
type Callback<T> = (argument: T) => ((next: T) => void) | Promise<void> | void | boolean;
|
|
179
|
+
type Callback<T> = (argument: T) => ((next: T | null) => void) | Promise<void> | void | boolean;
|
|
178
180
|
interface Object<T = any> {
|
|
179
|
-
(next: T): void;
|
|
181
|
+
(next: T | null): void;
|
|
180
182
|
current: T | null;
|
|
181
183
|
}
|
|
182
184
|
/** Object with references to all managed values of `T`. */
|
|
@@ -214,6 +216,16 @@ declare function ref<O extends Model, R>(target: O, mapper: (key: Model.Key<O>)
|
|
|
214
216
|
* @param callback - Optional callback to synchronously fire when reference is first set or does update.
|
|
215
217
|
*/
|
|
216
218
|
declare function ref<T = HTMLElement>(callback?: ref.Callback<T>): ref.Object<T>;
|
|
219
|
+
/**
|
|
220
|
+
* Creates a ref-compatible property.
|
|
221
|
+
* Will persist value, and updates to this are made part of controller event-stream.
|
|
222
|
+
*
|
|
223
|
+
* *Output is simultaneously a ref-function and ref-object, use as needed.*
|
|
224
|
+
*
|
|
225
|
+
* @param callback - Optional callback to synchronously fire when reference is first set or does update.
|
|
226
|
+
* @param ignoreNull - Default `true`. If `false`, will still callback with `null`.
|
|
227
|
+
*/
|
|
228
|
+
declare function ref<T = HTMLElement>(callback: ref.Callback<T | null>, ignoreNull: boolean): ref.Object<T>;
|
|
217
229
|
|
|
218
230
|
declare namespace set {
|
|
219
231
|
type Callback<T, S = any> = (this: S, argument: T) => ((next: T) => void) | Promise<any> | void | boolean;
|
package/lib/index.esm.js
CHANGED
|
@@ -40,7 +40,7 @@ function issues(register) {
|
|
|
40
40
|
return Library;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
43
|
+
const { assign, create, defineProperties, defineProperty, entries, keys, getPrototypeOf, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
44
44
|
|
|
45
45
|
const Oops$7 = issues({
|
|
46
46
|
NotFound: (name) => `Could not find ${name} in context.`
|
|
@@ -259,7 +259,7 @@ function createValueEffect(callback) {
|
|
|
259
259
|
return function (value) {
|
|
260
260
|
if (typeof unSet == "function")
|
|
261
261
|
unSet(value);
|
|
262
|
-
const out = callback.call(this, value
|
|
262
|
+
const out = callback.call(this, value);
|
|
263
263
|
if (typeof out == "boolean")
|
|
264
264
|
return out;
|
|
265
265
|
if (!out || out instanceof Promise)
|
|
@@ -275,18 +275,20 @@ function getMethod(argument, callback, once) {
|
|
|
275
275
|
if (typeof argument == "function")
|
|
276
276
|
return createEffect(this, argument);
|
|
277
277
|
const self = control(this, true);
|
|
278
|
-
function get() {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (!argument)
|
|
282
|
-
return Object.assign({}, self.state);
|
|
283
|
-
const output = {};
|
|
284
|
-
for (const key of argument)
|
|
285
|
-
output[key] = self.state[key];
|
|
286
|
-
return output;
|
|
278
|
+
function get(key) {
|
|
279
|
+
const value = self.state[key];
|
|
280
|
+
return value instanceof Model ? value.get() : value;
|
|
287
281
|
}
|
|
282
|
+
const extract = typeof argument == "string"
|
|
283
|
+
? () => get(argument)
|
|
284
|
+
: () => {
|
|
285
|
+
const output = {};
|
|
286
|
+
for (const key of argument || keys(self.state))
|
|
287
|
+
output[key] = get(key);
|
|
288
|
+
return output;
|
|
289
|
+
};
|
|
288
290
|
if (typeof callback != "function")
|
|
289
|
-
return
|
|
291
|
+
return extract();
|
|
290
292
|
const select = typeof argument == "string" ? [argument] : argument;
|
|
291
293
|
if (select)
|
|
292
294
|
for (const key of select)
|
|
@@ -302,7 +304,7 @@ function getMethod(argument, callback, once) {
|
|
|
302
304
|
if (!select || select.includes(key)) {
|
|
303
305
|
if (once)
|
|
304
306
|
remove();
|
|
305
|
-
return () => callback(
|
|
307
|
+
return () => callback(extract(), self.latest);
|
|
306
308
|
}
|
|
307
309
|
});
|
|
308
310
|
return remove;
|
|
@@ -370,20 +372,38 @@ class Model {
|
|
|
370
372
|
*
|
|
371
373
|
* Will determine if provided class is a subtype of this one.
|
|
372
374
|
*/
|
|
373
|
-
static
|
|
375
|
+
static is(maybe) {
|
|
374
376
|
return (typeof maybe == "function" &&
|
|
375
377
|
maybe.prototype instanceof this);
|
|
376
378
|
}
|
|
377
379
|
}
|
|
378
380
|
Model.get = get$1;
|
|
379
381
|
Model.use = use$1;
|
|
382
|
+
defineProperty(Model, "toString", {
|
|
383
|
+
value() {
|
|
384
|
+
return this.name;
|
|
385
|
+
}
|
|
386
|
+
});
|
|
380
387
|
defineProperties(Model.prototype, {
|
|
381
388
|
get: { value: getMethod },
|
|
382
389
|
set: { value: setMethod },
|
|
390
|
+
toString: {
|
|
391
|
+
configurable: true,
|
|
392
|
+
value() {
|
|
393
|
+
return `${this.constructor.name}-${control(this).id}`;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
/* TODO: Remove below on 1.0.0 release. */
|
|
398
|
+
defineProperty(Model, "isTypeof", {
|
|
399
|
+
get() {
|
|
400
|
+
throw new Error("Model.isTypeof method was renamed. Use Model.is instead.");
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
defineProperties(Model.prototype, {
|
|
383
404
|
is: {
|
|
384
405
|
configurable: true,
|
|
385
406
|
get() {
|
|
386
|
-
// TODO: Remove this method on 1.0
|
|
387
407
|
throw new Error("Model.is property is now is only available from a hook.");
|
|
388
408
|
}
|
|
389
409
|
},
|
|
@@ -391,20 +411,8 @@ defineProperties(Model.prototype, {
|
|
|
391
411
|
configurable: true,
|
|
392
412
|
writable: true,
|
|
393
413
|
value() {
|
|
394
|
-
// TODO: Remove this method on 1.0
|
|
395
414
|
throw new Error("Model.on() is deprecated. Use Model.get or Model.set instead.");
|
|
396
415
|
}
|
|
397
|
-
},
|
|
398
|
-
toString: {
|
|
399
|
-
configurable: true,
|
|
400
|
-
value() {
|
|
401
|
-
return `${this.constructor.name}-${control(this).id}`;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
});
|
|
405
|
-
defineProperty(Model, "toString", {
|
|
406
|
-
value() {
|
|
407
|
-
return this.name;
|
|
408
416
|
}
|
|
409
417
|
});
|
|
410
418
|
|
|
@@ -649,7 +657,7 @@ function get(arg0, arg1) {
|
|
|
649
657
|
let source = cb => cb(subject);
|
|
650
658
|
if (arg0 instanceof Model)
|
|
651
659
|
subject = arg0;
|
|
652
|
-
else if (Model.
|
|
660
|
+
else if (Model.is(arg0)) {
|
|
653
661
|
const hasParent = parent(subject);
|
|
654
662
|
if (!hasParent) {
|
|
655
663
|
if (arg1 === true)
|
|
@@ -770,11 +778,9 @@ Control.before.add(flushComputed);
|
|
|
770
778
|
function ref(arg, mapper) {
|
|
771
779
|
return apply((key, source) => {
|
|
772
780
|
let value = {};
|
|
773
|
-
if (typeof arg
|
|
774
|
-
value = createRef(source, key, arg);
|
|
775
|
-
else
|
|
781
|
+
if (typeof arg == "object")
|
|
776
782
|
for (const key in control(arg, true).state) {
|
|
777
|
-
defineProperty(value, key, mapper ? {
|
|
783
|
+
defineProperty(value, key, typeof mapper == "function" ? {
|
|
778
784
|
configurable: true,
|
|
779
785
|
get() {
|
|
780
786
|
const out = mapper(key);
|
|
@@ -785,6 +791,10 @@ function ref(arg, mapper) {
|
|
|
785
791
|
value: createRef(source, key)
|
|
786
792
|
});
|
|
787
793
|
}
|
|
794
|
+
else
|
|
795
|
+
value = createRef(source, key, arg && mapper !== false
|
|
796
|
+
? (x) => x !== null ? arg(x) : undefined
|
|
797
|
+
: arg);
|
|
788
798
|
source.state[key] = undefined;
|
|
789
799
|
source.observers.set(key, new Set());
|
|
790
800
|
defineProperty(source.subject, key, { value });
|
package/lib/index.js
CHANGED
|
@@ -44,7 +44,7 @@ function issues(register) {
|
|
|
44
44
|
return Library;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
47
|
+
const { assign, create, defineProperties, defineProperty, entries, keys, getPrototypeOf, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
48
48
|
|
|
49
49
|
const Oops$7 = issues({
|
|
50
50
|
NotFound: (name) => `Could not find ${name} in context.`
|
|
@@ -263,7 +263,7 @@ function createValueEffect(callback) {
|
|
|
263
263
|
return function (value) {
|
|
264
264
|
if (typeof unSet == "function")
|
|
265
265
|
unSet(value);
|
|
266
|
-
const out = callback.call(this, value
|
|
266
|
+
const out = callback.call(this, value);
|
|
267
267
|
if (typeof out == "boolean")
|
|
268
268
|
return out;
|
|
269
269
|
if (!out || out instanceof Promise)
|
|
@@ -279,18 +279,20 @@ function getMethod(argument, callback, once) {
|
|
|
279
279
|
if (typeof argument == "function")
|
|
280
280
|
return createEffect(this, argument);
|
|
281
281
|
const self = control(this, true);
|
|
282
|
-
function get() {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (!argument)
|
|
286
|
-
return Object.assign({}, self.state);
|
|
287
|
-
const output = {};
|
|
288
|
-
for (const key of argument)
|
|
289
|
-
output[key] = self.state[key];
|
|
290
|
-
return output;
|
|
282
|
+
function get(key) {
|
|
283
|
+
const value = self.state[key];
|
|
284
|
+
return value instanceof Model ? value.get() : value;
|
|
291
285
|
}
|
|
286
|
+
const extract = typeof argument == "string"
|
|
287
|
+
? () => get(argument)
|
|
288
|
+
: () => {
|
|
289
|
+
const output = {};
|
|
290
|
+
for (const key of argument || keys(self.state))
|
|
291
|
+
output[key] = get(key);
|
|
292
|
+
return output;
|
|
293
|
+
};
|
|
292
294
|
if (typeof callback != "function")
|
|
293
|
-
return
|
|
295
|
+
return extract();
|
|
294
296
|
const select = typeof argument == "string" ? [argument] : argument;
|
|
295
297
|
if (select)
|
|
296
298
|
for (const key of select)
|
|
@@ -306,7 +308,7 @@ function getMethod(argument, callback, once) {
|
|
|
306
308
|
if (!select || select.includes(key)) {
|
|
307
309
|
if (once)
|
|
308
310
|
remove();
|
|
309
|
-
return () => callback(
|
|
311
|
+
return () => callback(extract(), self.latest);
|
|
310
312
|
}
|
|
311
313
|
});
|
|
312
314
|
return remove;
|
|
@@ -374,20 +376,38 @@ class Model {
|
|
|
374
376
|
*
|
|
375
377
|
* Will determine if provided class is a subtype of this one.
|
|
376
378
|
*/
|
|
377
|
-
static
|
|
379
|
+
static is(maybe) {
|
|
378
380
|
return (typeof maybe == "function" &&
|
|
379
381
|
maybe.prototype instanceof this);
|
|
380
382
|
}
|
|
381
383
|
}
|
|
382
384
|
Model.get = get$1;
|
|
383
385
|
Model.use = use$1;
|
|
386
|
+
defineProperty(Model, "toString", {
|
|
387
|
+
value() {
|
|
388
|
+
return this.name;
|
|
389
|
+
}
|
|
390
|
+
});
|
|
384
391
|
defineProperties(Model.prototype, {
|
|
385
392
|
get: { value: getMethod },
|
|
386
393
|
set: { value: setMethod },
|
|
394
|
+
toString: {
|
|
395
|
+
configurable: true,
|
|
396
|
+
value() {
|
|
397
|
+
return `${this.constructor.name}-${control(this).id}`;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
/* TODO: Remove below on 1.0.0 release. */
|
|
402
|
+
defineProperty(Model, "isTypeof", {
|
|
403
|
+
get() {
|
|
404
|
+
throw new Error("Model.isTypeof method was renamed. Use Model.is instead.");
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
defineProperties(Model.prototype, {
|
|
387
408
|
is: {
|
|
388
409
|
configurable: true,
|
|
389
410
|
get() {
|
|
390
|
-
// TODO: Remove this method on 1.0
|
|
391
411
|
throw new Error("Model.is property is now is only available from a hook.");
|
|
392
412
|
}
|
|
393
413
|
},
|
|
@@ -395,20 +415,8 @@ defineProperties(Model.prototype, {
|
|
|
395
415
|
configurable: true,
|
|
396
416
|
writable: true,
|
|
397
417
|
value() {
|
|
398
|
-
// TODO: Remove this method on 1.0
|
|
399
418
|
throw new Error("Model.on() is deprecated. Use Model.get or Model.set instead.");
|
|
400
419
|
}
|
|
401
|
-
},
|
|
402
|
-
toString: {
|
|
403
|
-
configurable: true,
|
|
404
|
-
value() {
|
|
405
|
-
return `${this.constructor.name}-${control(this).id}`;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
defineProperty(Model, "toString", {
|
|
410
|
-
value() {
|
|
411
|
-
return this.name;
|
|
412
420
|
}
|
|
413
421
|
});
|
|
414
422
|
|
|
@@ -653,7 +661,7 @@ function get(arg0, arg1) {
|
|
|
653
661
|
let source = cb => cb(subject);
|
|
654
662
|
if (arg0 instanceof Model)
|
|
655
663
|
subject = arg0;
|
|
656
|
-
else if (Model.
|
|
664
|
+
else if (Model.is(arg0)) {
|
|
657
665
|
const hasParent = parent(subject);
|
|
658
666
|
if (!hasParent) {
|
|
659
667
|
if (arg1 === true)
|
|
@@ -774,11 +782,9 @@ Control.before.add(flushComputed);
|
|
|
774
782
|
function ref(arg, mapper) {
|
|
775
783
|
return apply((key, source) => {
|
|
776
784
|
let value = {};
|
|
777
|
-
if (typeof arg
|
|
778
|
-
value = createRef(source, key, arg);
|
|
779
|
-
else
|
|
785
|
+
if (typeof arg == "object")
|
|
780
786
|
for (const key in control(arg, true).state) {
|
|
781
|
-
defineProperty(value, key, mapper ? {
|
|
787
|
+
defineProperty(value, key, typeof mapper == "function" ? {
|
|
782
788
|
configurable: true,
|
|
783
789
|
get() {
|
|
784
790
|
const out = mapper(key);
|
|
@@ -789,6 +795,10 @@ function ref(arg, mapper) {
|
|
|
789
795
|
value: createRef(source, key)
|
|
790
796
|
});
|
|
791
797
|
}
|
|
798
|
+
else
|
|
799
|
+
value = createRef(source, key, arg && mapper !== false
|
|
800
|
+
? (x) => x !== null ? arg(x) : undefined
|
|
801
|
+
: arg);
|
|
792
802
|
source.state[key] = undefined;
|
|
793
803
|
source.observers.set(key, new Set());
|
|
794
804
|
defineProperty(source.subject, key, { value });
|
package/package.json
CHANGED