@expressive/mvc 1.0.0-beta.15 → 1.0.0-beta.17
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.js +42 -11
- package/package.json +1 -1
- package/types/instructions.d.ts +30 -14
- package/types/model.d.ts +3 -0
- package/types/types.d.ts +1 -0
package/lib/index.js
CHANGED
|
@@ -47,7 +47,8 @@ function setAlias(func, displayName) {
|
|
|
47
47
|
function createEffect(callback) {
|
|
48
48
|
let unSet;
|
|
49
49
|
return function (value) {
|
|
50
|
-
typeof unSet == "function"
|
|
50
|
+
if (typeof unSet == "function")
|
|
51
|
+
unSet();
|
|
51
52
|
unSet = callback.call(this, value);
|
|
52
53
|
if (unSet instanceof Promise)
|
|
53
54
|
unSet = undefined;
|
|
@@ -55,6 +56,22 @@ function createEffect(callback) {
|
|
|
55
56
|
throw Oops$8.BadEffectCallback();
|
|
56
57
|
};
|
|
57
58
|
}
|
|
59
|
+
function createValueEffect(callback) {
|
|
60
|
+
let unSet;
|
|
61
|
+
return function (value) {
|
|
62
|
+
if (typeof unSet == "function")
|
|
63
|
+
unSet(value);
|
|
64
|
+
const out = callback.call(this, value);
|
|
65
|
+
if (typeof out == "boolean")
|
|
66
|
+
return out;
|
|
67
|
+
if (!out || out instanceof Promise)
|
|
68
|
+
return;
|
|
69
|
+
if (typeof out == "function")
|
|
70
|
+
unSet = out;
|
|
71
|
+
else
|
|
72
|
+
throw Oops$8.BadEffectCallback();
|
|
73
|
+
};
|
|
74
|
+
}
|
|
58
75
|
function select(source, select) {
|
|
59
76
|
const proxy = {};
|
|
60
77
|
for (const k in source)
|
|
@@ -447,10 +464,11 @@ function flush(on) {
|
|
|
447
464
|
}
|
|
448
465
|
|
|
449
466
|
const Oops$6 = issues({
|
|
450
|
-
DuplicateAction: (key) => `Invoked action ${key} but one is already active
|
|
467
|
+
DuplicateAction: (key) => `Invoked action ${key} but one is already active.`,
|
|
468
|
+
SourceNotSupported: () => `Computed from-instruction does not support source other than 'this'.`
|
|
451
469
|
});
|
|
452
|
-
const set = (
|
|
453
|
-
let output =
|
|
470
|
+
const set = (fn, name) => does(function set(key) {
|
|
471
|
+
let output = fn.call(this, key, this);
|
|
454
472
|
if (typeof output == "function") {
|
|
455
473
|
const getter = output;
|
|
456
474
|
output = Object.assign(Object.assign({}, getOwnPropertyDescriptor(this.subject, key)), { get() {
|
|
@@ -459,9 +477,9 @@ const set = (instruction, name) => does(function set(key) {
|
|
|
459
477
|
}
|
|
460
478
|
if (output)
|
|
461
479
|
defineProperty(this.subject, key, output);
|
|
462
|
-
}, name ||
|
|
480
|
+
}, name || fn.name || "pending");
|
|
463
481
|
const ref = (cb) => set(function ref(key) {
|
|
464
|
-
const refObjectFunction = this.setter(key, cb &&
|
|
482
|
+
const refObjectFunction = this.setter(key, cb && createValueEffect(cb));
|
|
465
483
|
defineProperty(refObjectFunction, "current", {
|
|
466
484
|
set: refObjectFunction,
|
|
467
485
|
get: () => this.state[key]
|
|
@@ -470,8 +488,8 @@ const ref = (cb) => set(function ref(key) {
|
|
|
470
488
|
value: refObjectFunction
|
|
471
489
|
};
|
|
472
490
|
});
|
|
473
|
-
const on = (
|
|
474
|
-
this.manage(key,
|
|
491
|
+
const on = (initial, cb) => set(function on(key) {
|
|
492
|
+
this.manage(key, initial, cb && createValueEffect(cb));
|
|
475
493
|
});
|
|
476
494
|
const memo = (factory, defer) => set(function memo(key) {
|
|
477
495
|
const source = this.subject;
|
|
@@ -511,9 +529,19 @@ const act = (task) => set(function act(key) {
|
|
|
511
529
|
writable: false
|
|
512
530
|
};
|
|
513
531
|
});
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
532
|
+
function from(source, fn) {
|
|
533
|
+
return set(function from(key) {
|
|
534
|
+
let getter;
|
|
535
|
+
if (typeof source == "function")
|
|
536
|
+
getter = source.call(this.subject, key);
|
|
537
|
+
else {
|
|
538
|
+
if (source !== this.subject)
|
|
539
|
+
throw Oops$6.SourceNotSupported();
|
|
540
|
+
getter = fn;
|
|
541
|
+
}
|
|
542
|
+
prepare(this, key, getter);
|
|
543
|
+
});
|
|
544
|
+
}
|
|
517
545
|
|
|
518
546
|
const attach = (from, name) => set(function attach(key) {
|
|
519
547
|
const proxyCache = new WeakMap();
|
|
@@ -1058,6 +1086,9 @@ class Singleton extends Model {
|
|
|
1058
1086
|
instance.import(updates);
|
|
1059
1087
|
return instance.update();
|
|
1060
1088
|
}
|
|
1089
|
+
static is() {
|
|
1090
|
+
return this.find(true);
|
|
1091
|
+
}
|
|
1061
1092
|
static find(strict) {
|
|
1062
1093
|
const instance = this.current;
|
|
1063
1094
|
if (!instance && strict)
|
package/package.json
CHANGED
package/types/instructions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Model from '.';
|
|
2
|
-
import { Async, Class,
|
|
1
|
+
import Model, { Selector } from '.';
|
|
2
|
+
import { Async, Class, InstanceOf, InterceptCallback } from './types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Run instruction as controller sets itself up.
|
|
@@ -99,15 +99,22 @@ export function tap <T extends typeof Model> (Type: T, callback?: (instance?: In
|
|
|
99
99
|
* @param required - Throw if instance of Type cannot be found.
|
|
100
100
|
*/
|
|
101
101
|
export function tap <T extends Class> (Type: T, required?: boolean): InstanceOf<T>;
|
|
102
|
-
|
|
102
|
+
|
|
103
103
|
/**
|
|
104
|
-
*
|
|
104
|
+
* Cause property to synchronously run effect upon update.
|
|
105
|
+
*
|
|
106
|
+
* Callback may return an effect callback, Promise (ignored), or a boolean.
|
|
107
|
+
*
|
|
108
|
+
* If a boolean is returned explicitly, new value will be dropped. Useful to override.
|
|
109
|
+
*
|
|
110
|
+
* - `false` will prevent update.
|
|
111
|
+
* - `true` will emit update (unchanged).
|
|
105
112
|
*
|
|
106
|
-
* @param
|
|
107
|
-
* @param
|
|
113
|
+
* @param initialValue - Beginning value of host property.
|
|
114
|
+
* @param onUpdate - Effect-callback fired upon set of host property.
|
|
108
115
|
*/
|
|
109
|
-
export function on <T = any> (
|
|
110
|
-
export function on <T = any> (
|
|
116
|
+
export function on <T = any> (initialValue: undefined, onUpdate: InterceptCallback<T>): T | undefined;
|
|
117
|
+
export function on <T = any> (initialValue: T, onUpdate: InterceptCallback<T>): T;
|
|
111
118
|
|
|
112
119
|
/**
|
|
113
120
|
* Creates a ref-compatible property for use with components.
|
|
@@ -117,7 +124,7 @@ export function on <T = any> (initial: T, callback: EffectCallback<T>): T;
|
|
|
117
124
|
*
|
|
118
125
|
* @param callback - Optional callback to synchronously fire when reference is first set or does update.
|
|
119
126
|
*/
|
|
120
|
-
export function ref <T = HTMLElement> (this: any, callback?:
|
|
127
|
+
export function ref <T = HTMLElement> (this: any, callback?: InterceptCallback<T>): Model.Ref<T>;
|
|
121
128
|
|
|
122
129
|
/**
|
|
123
130
|
* Sets an exotic method with managed ready-state. Property accepts an async function.
|
|
@@ -130,15 +137,24 @@ export function ref <T = HTMLElement> (this: any, callback?: (value: T) => Callb
|
|
|
130
137
|
* @param action - Action to fire when resulting property is invoked.
|
|
131
138
|
*/
|
|
132
139
|
export function act <T extends Async> (action: T): T & { active: boolean };
|
|
133
|
-
|
|
140
|
+
|
|
134
141
|
/**
|
|
135
|
-
* Implement a computed value; output
|
|
142
|
+
* Implement a computed value; output is returned by function from provided factory.
|
|
136
143
|
*
|
|
137
|
-
*
|
|
144
|
+
* @param fn - Factory function to generate a getter to subscribe dependancies.
|
|
145
|
+
*/
|
|
146
|
+
export function from <R> (fn: (property: string) => (this: any, on: any) => R): R;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Implement a computed value; output will be generated by provided function.
|
|
138
150
|
*
|
|
139
|
-
* @param
|
|
151
|
+
* @param source - Source model from which computed value will be subscribed.
|
|
152
|
+
* **Note:** Currently will only support `this`.
|
|
153
|
+
*
|
|
154
|
+
* @param fn - Compute function. Bound to a subscriber-proxy of source, returns output value.
|
|
155
|
+
* Will update automatically as accessed values change.
|
|
140
156
|
*/
|
|
141
|
-
export function from <T, R> (fn: (this: T, on: T) => R): R;
|
|
157
|
+
export function from <T, R> (source: T, fn: (this: T, on: T) => R): R;
|
|
142
158
|
|
|
143
159
|
/**
|
|
144
160
|
* Memoized value. Computes and stores a value returned by provided factory.
|
package/types/model.d.ts
CHANGED
|
@@ -476,6 +476,9 @@ export abstract class Model extends State {
|
|
|
476
476
|
}
|
|
477
477
|
|
|
478
478
|
export class Singleton extends Model {
|
|
479
|
+
/** Get current instance of this singleton. Will throw if one does not exist. */
|
|
480
|
+
static is<T extends Class>(this: T): InstanceOf<T>;
|
|
481
|
+
|
|
479
482
|
/**
|
|
480
483
|
* Update the active instance of this class.
|
|
481
484
|
* Returns a thenable; resolves after successful update.
|
package/types/types.d.ts
CHANGED
|
@@ -10,5 +10,6 @@ export type Callback = () => void;
|
|
|
10
10
|
export type RequestCallback = (keys?: string[]) => void;
|
|
11
11
|
export type EffectCallback<T, A = T> = (this: T, argument: A) => Callback | Promise<any> | void;
|
|
12
12
|
export type UpdateCallback<T, P> = (this: T, value: IfApplicable<T, P>, changed: P) => void;
|
|
13
|
+
export type InterceptCallback<T> = (argument: T) => ((next: T) => void) | Promise<any> | void | boolean;
|
|
13
14
|
|
|
14
15
|
export type RefFunction = (e: HTMLElement | null) => void;
|