@expressive/mvc 1.0.0-beta.10 → 1.0.0-beta.14
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 +662 -597
- package/package.json +2 -2
- package/types/index.d.ts +1 -0
- package/types/instructions.d.ts +130 -81
- package/types/model.d.ts +139 -72
- package/types/selector.ts +18 -0
- package/types/dispatch.d.ts +0 -55
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expressive/mvc",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.14",
|
|
4
4
|
"description": "Use classes to define state in React!",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Gabe Klein",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"watch": "rollup --config --sourcemap --watch",
|
|
28
28
|
"prebuild": "rm -rf lib/",
|
|
29
29
|
"publish:pre": "npm version prerelease --preid=beta",
|
|
30
|
-
"preversion": "jest",
|
|
30
|
+
"preversion": "jest --coverage",
|
|
31
31
|
"postversion": "npm run build; npm publish",
|
|
32
32
|
"postpublish": "git push; git push --tags; rm -rf lib",
|
|
33
33
|
"coverage": "jest --collectCoverage",
|
package/types/index.d.ts
CHANGED
package/types/instructions.d.ts
CHANGED
|
@@ -5,104 +5,153 @@ import { Async, Class, EffectCallback, InstanceOf } from './types';
|
|
|
5
5
|
* Run instruction as controller sets itself up.
|
|
6
6
|
* This will specialize the behavior of a given property.
|
|
7
7
|
**/
|
|
8
|
-
export function set <T = any> (
|
|
9
|
-
instruction: Model.Instruction<T>,
|
|
10
|
-
name?: string
|
|
11
|
-
): T;
|
|
8
|
+
export function set <T = any> (instruction: Model.Instruction<T>, name?: string): T;
|
|
12
9
|
|
|
13
10
|
/**
|
|
14
11
|
* Creates a new child-instance of specified controller.
|
|
15
|
-
*
|
|
12
|
+
*
|
|
16
13
|
* @param Peer - Type of Model to create and apply to host property.
|
|
17
14
|
* @param callback - Fired after controller is created and ready for use.
|
|
18
15
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
export function use <T extends Class> (Peer: T, callback: (i?: InstanceOf<T>) => void): InstanceOf<T> | undefined;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new child-instance of specified controller.
|
|
20
|
+
*
|
|
21
|
+
* @param Peer - Type of Model to create and apply to host property.
|
|
22
|
+
* @param required - Property should be non-nullable, will throw if value is set to undefined.
|
|
23
|
+
*/
|
|
24
|
+
export function use <T extends Class> (Peer: T, required: false): InstanceOf<T> | undefined;
|
|
25
|
+
export function use <T extends Class> (Peer: T, required?: true): InstanceOf<T>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new child-instance of specified controller.
|
|
29
|
+
*
|
|
30
|
+
* @param factory - Generate model for use.
|
|
31
|
+
* @param callback - Fired after controller is created and ready for use.
|
|
32
|
+
*/
|
|
33
|
+
export function use <T extends Model | undefined> (factory: () => T, callback?: (i: T) => void): T;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Create a child-instance relationship with provided model.
|
|
37
|
+
*
|
|
38
|
+
* Note: If `peer` is not already initialized before parent is
|
|
39
|
+
* (created with `new` as opposed to create method), that model will
|
|
40
|
+
* attach this via `parent()` instruction. It will not howerver, if
|
|
41
|
+
* already active.
|
|
42
|
+
*
|
|
43
|
+
* @param factory - Instance of model to attach.
|
|
44
|
+
* @param callback - Fired after controller is attached.
|
|
45
|
+
*/
|
|
46
|
+
export function use <T extends Model> (peer: T, callback?: (i: T) => void): T;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create a placeholder for specified Model type.
|
|
50
|
+
*/
|
|
51
|
+
export function use <T extends Model> (): T | undefined;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Generate a child controller from specified object. Object's values are be trackable, as would be for a full-model.
|
|
55
|
+
*
|
|
56
|
+
* Note: Child will *not* be same object as one provided.
|
|
57
|
+
*/
|
|
58
|
+
export function use <T extends BunchOf<any>> (object: T): T;
|
|
24
59
|
|
|
25
60
|
/**
|
|
26
61
|
* Generic instruction used by `use()` and `tap()` for recursive subscription.
|
|
27
|
-
*
|
|
62
|
+
*
|
|
28
63
|
* @param from - Instruction body is run upon parent create. Return function to fetch current value of field.
|
|
29
64
|
*/
|
|
30
65
|
export function child <T extends Model> (from: (this: Model.Controller, key: string) => () => T | undefined): T;
|
|
31
66
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Fetches and assigns the controller which spawned this host.
|
|
69
|
+
* When parent assigns an instance via `use()` directive, it
|
|
70
|
+
* will be made available to child upon this request.
|
|
71
|
+
*
|
|
72
|
+
* @param Expects - Type of controller compatible with this class.
|
|
73
|
+
* @param required - Throw if controller is created independantly.
|
|
74
|
+
*/
|
|
75
|
+
export function parent <T extends typeof Model> (Expects: T, required: true): InstanceOf<T>;
|
|
76
|
+
export function parent <T extends typeof Model> (Expects: T, required?: false): InstanceOf<T> | undefined;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Find and attach most applicable instance of Model via context.
|
|
80
|
+
*
|
|
81
|
+
* Host controller will search element-hierarchy relative to where it spawned.
|
|
82
|
+
*
|
|
83
|
+
* @param Type - Type of model to find from context
|
|
84
|
+
* @param callback -
|
|
85
|
+
* - Invoked after context is scanned, is passed result - either found or undefined.
|
|
86
|
+
* - If argument is inadequate, but required, your implemention should simply throw.
|
|
87
|
+
* - If inadequate and not required, conditionally return false.
|
|
88
|
+
*/
|
|
89
|
+
export function tap <T extends typeof Model> (Type: T, callback?: (instance?: InstanceOf<T>) => void | true): InstanceOf<T>;
|
|
90
|
+
export function tap <T extends typeof Model> (Type: T, callback?: (instance?: InstanceOf<T>) => void | false): InstanceOf<T> | undefined;
|
|
42
91
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Find and attach most applicable instance of Model via context.
|
|
94
|
+
*
|
|
95
|
+
* Expects a `<Provider>` of target controller to exist.
|
|
96
|
+
* Host controller will search element-hierarchy relative to where it spawned.
|
|
97
|
+
*
|
|
98
|
+
* @param Type - Type of controller to attach to property.
|
|
99
|
+
* @param required - Throw if instance of Type cannot be found.
|
|
100
|
+
*/
|
|
101
|
+
export function tap <T extends Class> (Type: T, required?: boolean): InstanceOf<T>;
|
|
53
102
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Sets property to synchronously call effect upon update.
|
|
105
|
+
*
|
|
106
|
+
* @param starting - Beginning value of host property.
|
|
107
|
+
* @param callback - Effect-callback fired upon set of host property.
|
|
108
|
+
*/
|
|
109
|
+
export function on <T = any> (initial: undefined, callback: EffectCallback<T>): T | undefined;
|
|
110
|
+
export function on <T = any> (initial: T, callback: EffectCallback<T>): T;
|
|
62
111
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Creates a ref-compatible property for use with components.
|
|
114
|
+
* Will persist value, and updates to this are made part of controller event-stream.
|
|
115
|
+
*
|
|
116
|
+
* *Output is simultaneously a ref-function and ref-object, use as needed.*
|
|
117
|
+
*
|
|
118
|
+
* @param callback - Optional callback to synchronously fire when reference is first set or does update.
|
|
119
|
+
*/
|
|
120
|
+
export function ref <T = HTMLElement> (callback?: EffectCallback<T>): Model.Ref<T>;
|
|
72
121
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Sets an exotic method with managed ready-state. Property accepts an async function.
|
|
124
|
+
*
|
|
125
|
+
* When an act-method is invoked, its `active` property to true for duration of call.
|
|
126
|
+
* This is emitted as an update to property, both when called and after returns (or throws).
|
|
127
|
+
*
|
|
128
|
+
* **Note:** Subsequent calls will immediately throw if one is still pending.
|
|
129
|
+
*
|
|
130
|
+
* @param action - Action to fire when resulting property is invoked.
|
|
131
|
+
*/
|
|
132
|
+
export function act <T extends Async> (action: T): T & { active: boolean };
|
|
84
133
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
134
|
+
/**
|
|
135
|
+
* Implement a computed value; output will be generated by provided function.
|
|
136
|
+
*
|
|
137
|
+
* *Alternative to using native getters; works exactly the same!*
|
|
138
|
+
*
|
|
139
|
+
* @param fn - Factory function to generate value and subscribe dependancies.
|
|
140
|
+
*/
|
|
141
|
+
export function from <T, R> (fn: (this: T, on: T) => R): R;
|
|
93
142
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Memoized value. Computes and stores a value returned by provided factory.
|
|
145
|
+
* Equivalent to a getter, sans the automatic updates.
|
|
146
|
+
*
|
|
147
|
+
* @param compute - Factory for memoized value.
|
|
148
|
+
* @param lazy - Wait until accessed to introduce value.
|
|
149
|
+
*/
|
|
150
|
+
export function memo <T> (compute: () => T, lazy?: boolean): T;
|
|
102
151
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Flag property as not to be tracked. Useful if changes often with no real-time impact.
|
|
154
|
+
*
|
|
155
|
+
* @param value - starting value of property.
|
|
156
|
+
*/
|
|
157
|
+
export function lazy <T> (value?: T): T;
|
package/types/model.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import Dispatch from './dispatch';
|
|
2
1
|
import Lifecycle from './lifecycle';
|
|
3
|
-
import { Selector } from './selector';
|
|
2
|
+
import { Select, Selector } from './selector';
|
|
4
3
|
import { Class, InstanceOf, Key } from './types';
|
|
5
4
|
|
|
6
5
|
interface PropertyDescriptor<T> {
|
|
@@ -12,6 +11,12 @@ interface PropertyDescriptor<T> {
|
|
|
12
11
|
set?(v: T): void;
|
|
13
12
|
}
|
|
14
13
|
|
|
14
|
+
type Argument<T> = T extends (arg: infer U) => any ? U : never;
|
|
15
|
+
|
|
16
|
+
type Thenable<T> = {
|
|
17
|
+
then(onFulfilled: (arg: T) => void): void;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
export namespace Model {
|
|
16
21
|
/** Exotic value, actual value is contained. */
|
|
17
22
|
interface Ref<T = any> {
|
|
@@ -25,7 +30,7 @@ export namespace Model {
|
|
|
25
30
|
* Property initializer, will run upon instance creation.
|
|
26
31
|
* Optional returned callback will run when once upon first access.
|
|
27
32
|
*/
|
|
28
|
-
type Instruction<T> = (this: Controller, key: string) =>
|
|
33
|
+
type Instruction<T> = (this: Controller, key: string, thisArg: Controller) =>
|
|
29
34
|
void | GetFunction<T> | PropertyDescriptor<T>;
|
|
30
35
|
|
|
31
36
|
/** Shallow replacement given all entries of Model */
|
|
@@ -96,27 +101,26 @@ export namespace Model {
|
|
|
96
101
|
|
|
97
102
|
type SelectField<T> = (arg: Omit<T, keyof Model>) => any;
|
|
98
103
|
|
|
104
|
+
type SelectFieldKey<T> = Select.Key<Fields<T>>;
|
|
105
|
+
|
|
106
|
+
type Typeof<T, ST, X extends keyof T = Exclude<keyof T, keyof Model>> = {
|
|
107
|
+
[Key in X]: T[Key] extends ST ? Key : never;
|
|
108
|
+
}[X];
|
|
109
|
+
|
|
110
|
+
type SelectTypeof<T, ST> = Select.Key<Typeof<T, ST>>;
|
|
111
|
+
|
|
99
112
|
type HandleValue = (value: any) => boolean | void;
|
|
100
113
|
|
|
101
114
|
export class Controller {
|
|
102
115
|
state: BunchOf<any>;
|
|
103
116
|
subject: {};
|
|
104
117
|
|
|
105
|
-
/**
|
|
106
|
-
* Place a given key's property under management.
|
|
107
|
-
*
|
|
108
|
-
* Note: If property is occupied by an instruction, it will be run.
|
|
109
|
-
*/
|
|
110
|
-
add(key: string): void;
|
|
111
|
-
|
|
112
118
|
/** Add property to managed state. */
|
|
113
119
|
manage(key: string, initial: any, effect?: HandleValue): void;
|
|
114
120
|
|
|
115
121
|
select(using?: Query): string[];
|
|
116
122
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
watch(target: string | Iterable<string> | Query, handler: Function, squash?: boolean, once?: boolean): Callback;
|
|
123
|
+
setter(key: string, effect?: HandleValue): (value: any) => boolean | void;
|
|
120
124
|
|
|
121
125
|
addListener(batch: BunchOf<RequestCallback>): Callback;
|
|
122
126
|
|
|
@@ -125,17 +129,16 @@ export namespace Model {
|
|
|
125
129
|
include(cb: RequestCallback): void;
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
type Listener = {
|
|
129
|
-
commit(): void;
|
|
130
|
-
release(): void;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
132
|
export class Subscriber {
|
|
134
133
|
proxy: any;
|
|
134
|
+
source: any;
|
|
135
|
+
parent: Controller;
|
|
135
136
|
active: boolean;
|
|
136
137
|
follows: BunchOf<Callback>;
|
|
137
|
-
dependant: Set<
|
|
138
|
-
|
|
138
|
+
dependant: Set<{
|
|
139
|
+
commit(): void;
|
|
140
|
+
release(): void;
|
|
141
|
+
}>;
|
|
139
142
|
|
|
140
143
|
follow(key: string, cb?: Callback | undefined): void;
|
|
141
144
|
commit(): Callback;
|
|
@@ -148,9 +151,16 @@ declare const CONTROL: unique symbol;
|
|
|
148
151
|
declare const LOCAL: unique symbol;
|
|
149
152
|
declare const STATE: unique symbol;
|
|
150
153
|
|
|
151
|
-
export
|
|
154
|
+
export abstract class State {
|
|
155
|
+
/** Controller for this instance. */
|
|
156
|
+
[CONTROL]: Model.Controller;
|
|
157
|
+
|
|
158
|
+
/** Current state of this instance. */
|
|
159
|
+
[STATE]?: Model.State<this>;
|
|
160
|
+
|
|
161
|
+
/** Current subscriber (if present) while used in a live context (e.g. hook or effect). */
|
|
162
|
+
[LOCAL]?: Model.Subscriber;
|
|
152
163
|
|
|
153
|
-
export abstract class Model {
|
|
154
164
|
/**
|
|
155
165
|
* Circular reference to `this` controller.
|
|
156
166
|
*
|
|
@@ -210,6 +220,36 @@ export abstract class Model {
|
|
|
210
220
|
*/
|
|
211
221
|
set: this;
|
|
212
222
|
|
|
223
|
+
import <O extends Model.Data<this>> (via: O, select?: string[] | Model.SelectFields<this>): void;
|
|
224
|
+
|
|
225
|
+
export(): Model.State<this>;
|
|
226
|
+
export <P extends Model.Fields<this>> (select: P[]): Model.State<this, P>;
|
|
227
|
+
export <S extends Model.SelectFields<this>> (select: S): Model.State<this, Selector.From<S>>;
|
|
228
|
+
|
|
229
|
+
update(): PromiseLike<string[] | false>;
|
|
230
|
+
update(strict: true): Promise<string[]>;
|
|
231
|
+
update(strict: false): Promise<false>;
|
|
232
|
+
update(strict: boolean): Promise<string[] | false>;
|
|
233
|
+
|
|
234
|
+
update(keys: Model.Fields<this>): Thenable<string[]>;
|
|
235
|
+
update(keys: Model.SelectFieldKey<this>): Thenable<string[]>;
|
|
236
|
+
|
|
237
|
+
update(keys: Model.Fields<this>, callMethod: boolean): PromiseLike<string[]>;
|
|
238
|
+
update(keys: Model.SelectFields<this>, callMethod: boolean): PromiseLike<string[]>;
|
|
239
|
+
|
|
240
|
+
update<T>(keys: Model.Fields<this>, argument: T): PromiseLike<string[]>;
|
|
241
|
+
update<T>(keys: Model.SelectFields<this>, argument: T): PromiseLike<string[]>;
|
|
242
|
+
|
|
243
|
+
/*
|
|
244
|
+
Issue with self-reference, using fallback.
|
|
245
|
+
|
|
246
|
+
update(keys: Model.Typeof<this, () => void>, callMethod: boolean): Thenable<string[]>;
|
|
247
|
+
update(keys: Model.SelectTypeof<this, () => void>, callMethod: boolean): Thenable<string[]>;
|
|
248
|
+
|
|
249
|
+
update<T>(keys: Model.Typeof<this, (arg: T) => void>, argument: T): Thenable<string[]>;
|
|
250
|
+
update<T>(keys: Model.SelectTypeof<this, (arg: T) => void>, argument: T): Thenable<string[]>;
|
|
251
|
+
*/
|
|
252
|
+
|
|
213
253
|
/**
|
|
214
254
|
* Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
|
|
215
255
|
*
|
|
@@ -239,33 +279,6 @@ export abstract class Model {
|
|
|
239
279
|
tap <K extends Model.SelectField<this>> (key: K, expect?: boolean): ReturnType<K>;
|
|
240
280
|
tap <K extends Model.SelectField<this>> (key: K, expect: true): Exclude<ReturnType<K>, undefined>;
|
|
241
281
|
|
|
242
|
-
/**
|
|
243
|
-
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
244
|
-
*
|
|
245
|
-
* This method will fire lifecycle events on given controller.
|
|
246
|
-
*
|
|
247
|
-
* @param id - Argument passed to controller-lifecycle methods. Use to identify the consumer.
|
|
248
|
-
*/
|
|
249
|
-
tag(id?: Key): this;
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
253
|
-
*
|
|
254
|
-
* This method will fire lifecycle events on given controller.
|
|
255
|
-
*
|
|
256
|
-
* @param idFactory - Will be invoked with fetched instance. Use this to register a tag as-needed.
|
|
257
|
-
*/
|
|
258
|
-
tag(idFactory: (idFactory: this) => Key | void): this;
|
|
259
|
-
|
|
260
|
-
/** Controller for this instance. */
|
|
261
|
-
[CONTROL]: Model.Controller;
|
|
262
|
-
|
|
263
|
-
/** Current state of this instance. */
|
|
264
|
-
[STATE]?: Model.State<this>;
|
|
265
|
-
|
|
266
|
-
/** Current subscriber (if present) while used in a live context (e.g. hook or effect). */
|
|
267
|
-
[LOCAL]?: Model.Subscriber;
|
|
268
|
-
|
|
269
282
|
/** Use symbol to access controller of a model. */
|
|
270
283
|
static CONTROL: typeof CONTROL;
|
|
271
284
|
|
|
@@ -289,8 +302,11 @@ export abstract class Model {
|
|
|
289
302
|
*
|
|
290
303
|
* Differs from `use()` in lacking subscription and lifecycle events.
|
|
291
304
|
* Much more efficient if you don't need hook-based features.
|
|
305
|
+
*
|
|
306
|
+
* @param args - Arguments passed to constructor of `this`
|
|
307
|
+
* @param callback - Run after creation of instance.
|
|
292
308
|
*/
|
|
293
|
-
static new <T extends Class> (this: T,
|
|
309
|
+
static new <T extends Class> (this: T, args?: ConstructorParameters<T>, callback?: (instance: InstanceOf<T>) => void): InstanceOf<T>;
|
|
294
310
|
|
|
295
311
|
/**
|
|
296
312
|
* **React Hook** - Create and attach an instance of this controller a react component.
|
|
@@ -298,8 +314,9 @@ export abstract class Model {
|
|
|
298
314
|
* Note: Model will be destroyed when ambient component unmounts!
|
|
299
315
|
*
|
|
300
316
|
* @param args - Arguments passed to constructor of `this`
|
|
317
|
+
* @param callback - Run after creation of instance.
|
|
301
318
|
*/
|
|
302
|
-
static use <T extends Class> (this: T,
|
|
319
|
+
static use <T extends Class> (this: T, args?: ConstructorParameters<T>, callback?: (instance: InstanceOf<T>) => void): InstanceOf<T>;
|
|
303
320
|
|
|
304
321
|
/**
|
|
305
322
|
* **React Hook** - Similar to `use`, will instanciate a controller bound to ambient component.
|
|
@@ -307,7 +324,7 @@ export abstract class Model {
|
|
|
307
324
|
*
|
|
308
325
|
* @param data - Data to be applied to controller upon creation.
|
|
309
326
|
*/
|
|
310
|
-
static uses <T extends Class, I extends InstanceOf<T>, D extends Partial<I>> (this: T, data: D): I;
|
|
327
|
+
static uses <T extends Class, I extends InstanceOf<T>, D extends Partial<I>> (this: T, data: D, only?: (keyof D)[]): I;
|
|
311
328
|
|
|
312
329
|
/**
|
|
313
330
|
* **React Hook** - Similar to `uses`, will instanciate a controller includive of given data.
|
|
@@ -316,7 +333,13 @@ export abstract class Model {
|
|
|
316
333
|
*
|
|
317
334
|
* @param data - Data to be observed by controller.
|
|
318
335
|
*/
|
|
319
|
-
static using <T extends Class, I extends InstanceOf<T>, D extends Partial<I>> (this: T, data: D): I;
|
|
336
|
+
static using <T extends Class, I extends InstanceOf<T>, D extends Partial<I>> (this: T, data: D, only?: (keyof D)[]): I;
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* **React Hook** - Locate most relevant instance of this type in context.
|
|
340
|
+
*/
|
|
341
|
+
static find <T extends Class>(this: T, strict: true): InstanceOf<T>;
|
|
342
|
+
static find <T extends Class>(this: T, strict?: boolean): InstanceOf<T> | undefined;
|
|
320
343
|
|
|
321
344
|
/**
|
|
322
345
|
* **React Hook** - Fetch most instance of this controller from context, if it exists.
|
|
@@ -362,6 +385,61 @@ export abstract class Model {
|
|
|
362
385
|
static tap <T extends Class, I extends InstanceOf<T>, K extends Model.Fields<I>> (this: T, key: K, expect: true): Exclude<I[K], undefined>;
|
|
363
386
|
static tap <T extends Class, I extends InstanceOf<T>, K extends Model.SelectField<I>> (this: T, key: K, expect: true): Exclude<ReturnType<K>, undefined>;
|
|
364
387
|
|
|
388
|
+
/**
|
|
389
|
+
* Static equivalent of `x instanceof this`.
|
|
390
|
+
*
|
|
391
|
+
* Will determine if provided class is a subtype of this one.
|
|
392
|
+
*/
|
|
393
|
+
static isTypeof <T extends Class>(this: T, subject: any): subject is T;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export interface Model extends Lifecycle {}
|
|
397
|
+
export abstract class Model extends State {
|
|
398
|
+
// Keyed
|
|
399
|
+
on <S extends Model.SelectEvents<this>> (via: S, cb: Selector.Callback<S, this>, squash?: false, once?: boolean): Callback;
|
|
400
|
+
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
|
|
401
|
+
// Squash
|
|
402
|
+
on <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true, once?: boolean): Callback;
|
|
403
|
+
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true, once?: boolean): Callback;
|
|
404
|
+
// Unknown
|
|
405
|
+
on <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean, once?: boolean): Callback;
|
|
406
|
+
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean, once?: boolean): Callback;
|
|
407
|
+
|
|
408
|
+
// Keyed
|
|
409
|
+
once <S extends Model.SelectEvents<this>> (via: S, cb: Selector.Callback<S, this>, squash?: false): Callback;
|
|
410
|
+
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false): Callback;
|
|
411
|
+
// Squash
|
|
412
|
+
once <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true): Callback;
|
|
413
|
+
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true): Callback;
|
|
414
|
+
// Promise
|
|
415
|
+
once <S extends Model.SelectEvents<this>> (via: S): Promise<Selector.From<S>[]>;
|
|
416
|
+
once <P extends Model.EventsCompat<this>> (key: P | P[]): Promise<P[]>;
|
|
417
|
+
// Unknown
|
|
418
|
+
once <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean): Callback;
|
|
419
|
+
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean): Callback;
|
|
420
|
+
|
|
421
|
+
effect(callback: (this: this, state: this) => void, select?: Model.SelectFields<this>): Callback;
|
|
422
|
+
effect(callback: (this: this, state: this) => void, select?: (keyof this)[]): Callback;
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
426
|
+
*
|
|
427
|
+
* This method will fire lifecycle events on given controller.
|
|
428
|
+
*
|
|
429
|
+
* @param id - Argument passed to controller-lifecycle methods. Use to identify the consumer.
|
|
430
|
+
*/
|
|
431
|
+
tag(id?: Key): this;
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
435
|
+
*
|
|
436
|
+
* This method will fire lifecycle events on given controller.
|
|
437
|
+
*
|
|
438
|
+
* @param idFactory - Will be invoked with fetched instance. Use this to register a tag as-needed.
|
|
439
|
+
*/
|
|
440
|
+
tag(idFactory: (idFactory: this) => Key | void): this;
|
|
441
|
+
|
|
442
|
+
|
|
365
443
|
/**
|
|
366
444
|
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
367
445
|
*
|
|
@@ -395,28 +473,17 @@ export abstract class Model {
|
|
|
395
473
|
* Documentation TBD.
|
|
396
474
|
*/
|
|
397
475
|
static meta <T extends Class, K extends Model.SelectField<T>> (this: T, key?: K): ReturnType<K>;
|
|
398
|
-
|
|
399
|
-
/**
|
|
400
|
-
* **React Hook** - Locate most relevant instance of this type in context.
|
|
401
|
-
*/
|
|
402
|
-
static find <T extends Class>(this: T): InstanceOf<T>;
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Static equivalent of `x instanceof this`.
|
|
406
|
-
*
|
|
407
|
-
* Will determine if provided class is a subtype of this one.
|
|
408
|
-
*/
|
|
409
|
-
static isTypeof <T extends Class>(this: T, subject: any): subject is T;
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Retreives parent inherited by this class, unless it is base `Model`.
|
|
413
|
-
*/
|
|
414
|
-
static inherits: typeof Model | undefined;
|
|
415
476
|
}
|
|
416
477
|
|
|
417
478
|
export class Singleton extends Model {
|
|
418
|
-
/**
|
|
419
|
-
|
|
479
|
+
/**
|
|
480
|
+
* Update the active instance of this class.
|
|
481
|
+
* Returns a thenable; resolves after successful update.
|
|
482
|
+
* If instance does not already exist, one will be created.
|
|
483
|
+
**/
|
|
484
|
+
static update<T extends Class>(
|
|
485
|
+
this: T, updates: Model.Data<InstanceOf<T>>
|
|
486
|
+
): PromiseLike<string[] | false>;
|
|
420
487
|
|
|
421
488
|
/** Destroy current instance of Singleton, if it exists. */
|
|
422
489
|
static reset(): void;
|
package/types/selector.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export type KeysOfType<T, ST> = {
|
|
2
|
+
[Key in keyof T]: T[Key] extends ST ? Key : never
|
|
3
|
+
}[keyof T];
|
|
4
|
+
|
|
1
5
|
export namespace Selector {
|
|
2
6
|
/**
|
|
3
7
|
* Shallow-recursive clone of source object.
|
|
@@ -26,4 +30,18 @@ export namespace Selector {
|
|
|
26
30
|
|
|
27
31
|
export type Gets<F extends Function<any>> =
|
|
28
32
|
F extends (spy: any) => infer R ? Values<R> : never;
|
|
33
|
+
|
|
34
|
+
export type Callback<S extends Function<any>, T> =
|
|
35
|
+
(this: T, value: Gets<S>, key: From<S>) => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export namespace Select {
|
|
39
|
+
export type One<T> =
|
|
40
|
+
(arg: { [K in keyof T]: K }) => string & keyof T;
|
|
41
|
+
|
|
42
|
+
export type Key<T extends string | number | symbol> =
|
|
43
|
+
(arg: { [K in T]: K }) => string & T;
|
|
44
|
+
|
|
45
|
+
export type From<T extends One<any>> =
|
|
46
|
+
T extends (from: any) => infer R ? R : never;
|
|
29
47
|
}
|
package/types/dispatch.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { Model } from './model';
|
|
2
|
-
import { Selector } from './selector';
|
|
3
|
-
import { Callback, EffectCallback, UpdateCallback } from './types';
|
|
4
|
-
|
|
5
|
-
type CallbackFor<S extends Selector.Function<any>, T> =
|
|
6
|
-
(this: T, value: Selector.Gets<S>, key: Selector.From<S>) => void;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Observable Instance
|
|
10
|
-
*
|
|
11
|
-
* Implements internal value tracking.
|
|
12
|
-
* Able to be subscribed to, per-value to know when updated.
|
|
13
|
-
*/
|
|
14
|
-
interface Dispatch {
|
|
15
|
-
// Keyed
|
|
16
|
-
on <S extends Model.SelectEvents<this>> (via: S, cb: CallbackFor<S, this>, squash?: false, once?: boolean): Callback;
|
|
17
|
-
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
|
|
18
|
-
// Squash
|
|
19
|
-
on <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true, once?: boolean): Callback;
|
|
20
|
-
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true, once?: boolean): Callback;
|
|
21
|
-
// Unknown
|
|
22
|
-
on <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean, once?: boolean): Callback;
|
|
23
|
-
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean, once?: boolean): Callback;
|
|
24
|
-
|
|
25
|
-
// Keyed
|
|
26
|
-
once <S extends Model.SelectEvents<this>> (via: S, cb: CallbackFor<S, this>, squash?: false): Callback;
|
|
27
|
-
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false): Callback;
|
|
28
|
-
// Squash
|
|
29
|
-
once <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true): Callback;
|
|
30
|
-
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true): Callback;
|
|
31
|
-
// Promise
|
|
32
|
-
once <S extends Model.SelectEvents<this>> (via: S): Promise<Selector.From<S>[]>;
|
|
33
|
-
once <P extends Model.EventsCompat<this>> (key: P | P[]): Promise<P[]>;
|
|
34
|
-
// Unknown
|
|
35
|
-
once <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean): Callback;
|
|
36
|
-
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean): Callback;
|
|
37
|
-
|
|
38
|
-
effect(callback: EffectCallback<this>, select?: Model.SelectFields<this>): Callback;
|
|
39
|
-
effect(callback: EffectCallback<this>, select?: (keyof this)[]): Callback;
|
|
40
|
-
|
|
41
|
-
import <O extends Model.Data<this>> (via: O, select?: string[] | Model.SelectFields<this>): void;
|
|
42
|
-
|
|
43
|
-
export(): Model.State<this>;
|
|
44
|
-
export <P extends Model.Fields<this>> (select: P[]): Model.State<this, P>;
|
|
45
|
-
export <S extends Model.SelectFields<this>> (select: S): Model.State<this, Selector.From<S>>;
|
|
46
|
-
|
|
47
|
-
update(strict: true): Promise<string[]>;
|
|
48
|
-
update(strict: false): Promise<false>;
|
|
49
|
-
update(strict?: boolean): Promise<string[] | false>;
|
|
50
|
-
update(keys: Model.Fields<this>[]): Promise<string[]>;
|
|
51
|
-
update(keys: Model.Fields<this>): Promise<string[]>;
|
|
52
|
-
update(keys: Model.SelectFields<this>): Promise<string[]>;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export = Dispatch;
|