@expressive/mvc 1.0.0-beta.34 → 1.0.0-beta.35

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.
@@ -1,5 +1,5 @@
1
1
  import Model from '.';
2
- import { Async, Class, InstanceOf, InterceptCallback } from './types';
2
+ import { Async, Class, InstanceOf } from './types';
3
3
 
4
4
  /**
5
5
  * Run instruction as controller sets itself up.
@@ -15,57 +15,22 @@ export function use <T extends Model> (): T | undefined;
15
15
  /**
16
16
  * Create a new child instance of model.
17
17
  */
18
- export function use <T extends Class> (Type: T): InstanceOf<T>;
19
-
20
- /**
21
- * Create a new child-instance of specified controller, in readonly mode.
22
- * Will prevent assignment of new value.
23
- *
24
- * **Note:** This is only enforced at runtime. Use
25
- * [`readonly`](https://www.typescriptlang.org/docs/handbook/2/classes.html#readonly), if writing in typescript.
26
- */
27
- export function use <T extends Class> (Type: T, readonly: true): InstanceOf<T>;
28
- export function use <T extends Model> (from: () => T, readonly: true): T;
29
-
30
- /**
31
- * Create a new child-instance of specified controller, in optional mode.
32
- * Will allow assignment of undefined, and likewise should be checked before usage.
33
- */
34
- export function use <T extends Class> (Type: T, required: false): InstanceOf<T> | undefined;
35
- export function use <T extends Model> (from: () => T | undefined, required: false): T | undefined;
36
-
37
- /**
38
- * Create a new child-instance of specified controller.
39
- *
40
- * By default, property is non-nullable. If callback returns `true` the first time, will be in readonly mode.
41
- * If callback returns false, property may also be set to undefined, as needed.
42
- */
43
- export function use <T extends Class> (Type: T, callback: (i: InstanceOf<T>) => true): InstanceOf<T>;
44
- export function use <T extends Class> (Type: T, callback: (i: InstanceOf<T>) => false): InstanceOf<T> | undefined;
45
- export function use <T extends Class> (Type: T, callback: (i: InstanceOf<T>) => void): InstanceOf<T>;
18
+ export function use <T extends Class> (Type: T, callback?: (i: InstanceOf<T>) => void): InstanceOf<T>;
46
19
 
47
20
  /**
48
21
  * Create a new child-instance from factory function.
49
22
  */
50
- export function use <T extends Model> (from: () => T): T;
51
- export function use <T extends Model> (from: () => T, callback: (i: T) => true): T;
52
- export function use <T extends Model> (from: () => T | undefined, callback: (i: T) => false): T | undefined;
53
- export function use <T extends Model> (from: () => T, callback: (i: T) => void): T;
23
+ export function use <T extends Model> (from: () => T, callback?: (i: T) => void): T;
54
24
 
55
25
  /**
56
- * Createa child-instance relationship with provided model.
26
+ * Create child-instance relationship with provided model.
57
27
  *
58
28
  * Note: If `peer` is not already initialized before parent is
59
29
  * (created with `new` as opposed to create method), that model will
60
30
  * attach this via `parent()` instruction. It will not, if
61
31
  * already active.
62
32
  */
63
- export function use <T extends Model> (peer: T): T;
64
- export function use <T extends Model> (peer: T, readonly: true): T;
65
- export function use <T extends Model> (peer: T, required: false): T | undefined;
66
- export function use <T extends Model> (peer: T, callback: (i: T) => true): T;
67
- export function use <T extends Model> (peer: T, callback: (i: T) => false): T | undefined;
68
- export function use <T extends Model> (peer: T, callback: (i: T) => void): T;
33
+ export function use <T extends Model> (peer: T, callback?: (i: T) => void): T;
69
34
 
70
35
  /**
71
36
  * Generate a child controller from specified object. Object's values are be trackable, as would be for a full-model.
@@ -74,12 +39,19 @@ export function use <T extends Model> (peer: T, callback: (i: T) => void): T;
74
39
  */
75
40
  export function use <T extends {}> (object: T): T;
76
41
 
42
+ export namespace child {
43
+ type Instruction<T> = (this: Model.Controller, key: string) => {
44
+ get: () => T | undefined,
45
+ set?: (value: T | undefined) => void
46
+ }
47
+ }
48
+
77
49
  /**
78
50
  * Generic instruction used by `use()` and `tap()` for recursive subscription.
79
51
  *
80
52
  * @param from - Instruction body is run upon parent create. Return function to fetch current value of field.
81
53
  */
82
- export function child <T extends Model> (from: (this: Model.Controller, key: string) => () => T | undefined): T;
54
+ export function child <T extends Model> (from: child.Instruction<T>): T;
83
55
 
84
56
  /**
85
57
  * Fetches and assigns the controller which spawned this host.
@@ -117,6 +89,11 @@ export function tap <T extends typeof Model> (Type: T, callback?: (instance?: In
117
89
  */
118
90
  export function tap <T extends Class> (Type: T, required?: boolean): InstanceOf<T>;
119
91
 
92
+ export namespace on {
93
+ type Callback<T, S = any> = (this: S, argument: T) =>
94
+ ((next: T) => void) | Promise<any> | void | boolean;
95
+ }
96
+
120
97
  /**
121
98
  * Cause property to synchronously run effect upon update.
122
99
  *
@@ -132,14 +109,19 @@ export function tap <T extends Class> (Type: T, required?: boolean): InstanceOf<
132
109
  *
133
110
  * @deprecated will be removed in favor of `set`
134
111
  */
135
- export function on <T> (initialValue: undefined, onUpdate: InterceptCallback<T>): T | undefined;
136
- export function on <T> (initialValue: T, onUpdate: InterceptCallback<T>): T;
137
- export function on <T, S> (initialValue: undefined, onUpdate: InterceptCallback<T, S>): T | undefined;
138
- export function on <T, S> (initialValue: T, onUpdate: InterceptCallback<T, S>): T;
112
+ export function on <T> (initialValue: undefined, onUpdate: on.Callback<T>): T | undefined;
113
+ export function on <T> (initialValue: T, onUpdate: on.Callback<T>): T;
114
+ export function on <T, S> (initialValue: undefined, onUpdate: on.Callback<T, S>): T | undefined;
115
+ export function on <T, S> (initialValue: T, onUpdate: on.Callback<T, S>): T;
139
116
 
140
117
  /** Object with references to all managed values of `T`. */
141
118
  export type Refs <T extends Model> = { [P in Model.Fields<T>]: Model.Ref<T[P]> };
142
119
 
120
+ export namespace ref {
121
+ type Callback<T, S = any> = (this: S, argument: T) =>
122
+ ((next: T) => void) | Promise<any> | void | boolean;
123
+ }
124
+
143
125
  /**
144
126
  * Creates an object with references to all managed values.
145
127
  * Each property will set value in state when invoked.
@@ -158,8 +140,8 @@ export function ref <T extends Model> (target: T): Refs<T>;
158
140
  *
159
141
  * @param callback - Optional callback to synchronously fire when reference is first set or does update.
160
142
  */
161
- export function ref <T = HTMLElement> (callback?: InterceptCallback<T>): Model.Ref<T>;
162
- export function ref <T, S> (callback?: InterceptCallback<T, S>): Model.Ref<T>;
143
+ export function ref <T = HTMLElement> (callback?: ref.Callback<T>): Model.Ref<T>;
144
+ export function ref <T, S> (callback?: ref.Callback<T, S>): Model.Ref<T>;
163
145
 
164
146
  /**
165
147
  * Sets an exotic method with managed ready-state. Property accepts an async function.
@@ -267,7 +249,12 @@ export function pending <R, T> (waitFor: (this: T) => Promise<R>): R;
267
249
  */
268
250
  export function pending <R, T> (source: T, compute: (this: T, on: T) => R): R; // ✅
269
251
 
270
- type FactoryFunction<T, S = unknown> = (this: S, key: string, subject: S) => T;
252
+ export namespace set {
253
+ type Factory<T, S = unknown> = (this: S, key: string, subject: S) => T;
254
+
255
+ type Callback<T, S = any> = (this: S, argument: T) =>
256
+ ((next: T) => void) | Promise<any> | void | boolean;
257
+ }
271
258
 
272
259
  /**
273
260
  * Set property with a placeholder.
@@ -289,8 +276,8 @@ type FactoryFunction<T, S = unknown> = (this: S, key: string, subject: S) => T;
289
276
  export function set <T> (value: undefined, required: false): T | undefined;
290
277
  export function set <T> (value: undefined, required?: boolean): T;
291
278
 
292
- export function set <T> (value: undefined, onUpdate: InterceptCallback<T>): T | undefined;
293
- export function set <T, S> (value: undefined, onUpdate: InterceptCallback<T, S>): T | undefined;
279
+ export function set <T> (value: undefined, onUpdate: set.Callback<T>): T | undefined;
280
+ export function set <T, S> (value: undefined, onUpdate: set.Callback<T, S>): T | undefined;
294
281
 
295
282
  /**
296
283
  * Set property with an async function.
@@ -307,14 +294,14 @@ type FactoryFunction<T, S = unknown> = (this: S, key: string, subject: S) => T;
307
294
  * @param factory - Callback run to derrive property value.
308
295
  * @param required - (default: true) Run factory immediately on creation, otherwise on access.
309
296
  */
310
- export function set <T>(factory: FactoryFunction<Promise<T>>, required: false): T | undefined;
311
- export function set <T, S>(factory: FactoryFunction<Promise<T>, S>, required: false): T | undefined;
297
+ export function set <T>(factory: set.Factory<Promise<T>>, required: false): T | undefined;
298
+ export function set <T, S>(factory: set.Factory<Promise<T>, S>, required: false): T | undefined;
312
299
 
313
- export function set <T>(factory: FactoryFunction<Promise<T>>, required?: boolean): T;
314
- export function set <T, S>(factory: FactoryFunction<Promise<T>, S>, required?: boolean): T;
300
+ export function set <T>(factory: set.Factory<Promise<T>>, required?: boolean): T;
301
+ export function set <T, S>(factory: set.Factory<Promise<T>, S>, required?: boolean): T;
315
302
 
316
- export function set <T> (value: FactoryFunction<Promise<T>>, onUpdate: InterceptCallback<T>): T;
317
- export function set <T, S> (value: FactoryFunction<Promise<T>, S>, onUpdate: InterceptCallback<T, S>): T;
303
+ export function set <T> (value: set.Factory<Promise<T>>, onUpdate: set.Callback<T>): T;
304
+ export function set <T, S> (value: set.Factory<Promise<T>, S>, onUpdate: set.Callback<T, S>): T;
318
305
 
319
306
  /**
320
307
  * Set property with a factory function.
@@ -328,12 +315,12 @@ type FactoryFunction<T, S = unknown> = (this: S, key: string, subject: S) => T;
328
315
  * @param factory - Callback run to derrive property value.
329
316
  * @param required - (default: true) Run factory immediately on creation, otherwise on access.
330
317
  */
331
- export function set <T>(factory: FactoryFunction<T>, required: false): T | undefined;
332
- export function set <T, S>(factory: FactoryFunction<T, S>, required: false): T | undefined;
318
+ export function set <T>(factory: set.Factory<T>, required: false): T | undefined;
319
+ export function set <T, S>(factory: set.Factory<T, S>, required: false): T | undefined;
333
320
 
334
- export function set <T>(factory: FactoryFunction<T>, required?: boolean): T;
335
- export function set <T, S>(factory: FactoryFunction<T, S>, required?: boolean): T;
321
+ export function set <T>(factory: set.Factory<T>, required?: boolean): T;
322
+ export function set <T, S>(factory: set.Factory<T, S>, required?: boolean): T;
336
323
 
337
- export function set <T> (value: FactoryFunction<T>, onUpdate: InterceptCallback<T>): T;
338
- export function set <T, S> (value: FactoryFunction<T, S>, onUpdate: InterceptCallback<T, S>): T;
324
+ export function set <T> (value: set.Factory<T>, onUpdate: set.Callback<T>): T;
325
+ export function set <T, S> (value: set.Factory<T, S>, onUpdate: set.Callback<T, S>): T;
339
326
 
@@ -1,4 +1,6 @@
1
- import { Key } from "./types";
1
+ declare namespace Lifecycle {
2
+ type Key = string | symbol | number;
3
+ }
2
4
 
3
5
  /**
4
6
  * Model-Component Lifecycle
@@ -8,17 +10,17 @@ import { Key } from "./types";
8
10
  * call these respectively to that component's lifecycle.
9
11
  */
10
12
  interface Lifecycle {
11
- didMount?(tag?: Key): void;
12
- willRender?(tag?: Key): void;
13
- willUpdate?(tag?: Key): void;
14
- willMount?(tag?: Key): void;
15
- willUnmount?(tag?: Key): void;
13
+ didMount?(tag?: Lifecycle.Key): void;
14
+ willRender?(tag?: Lifecycle.Key): void;
15
+ willUpdate?(tag?: Lifecycle.Key): void;
16
+ willMount?(tag?: Lifecycle.Key): void;
17
+ willUnmount?(tag?: Lifecycle.Key): void;
16
18
 
17
- elementDidMount?(tag: Key): void;
18
- elementWillRender?(tag: Key): void;
19
- elementWillUpdate?(tag: Key): void;
20
- elementWillMount?(tag: Key): void;
21
- elementWillUnmount?(tag: Key): void;
19
+ elementDidMount?(tag: Lifecycle.Key): void;
20
+ elementWillRender?(tag: Lifecycle.Key): void;
21
+ elementWillUpdate?(tag: Lifecycle.Key): void;
22
+ elementWillMount?(tag: Lifecycle.Key): void;
23
+ elementWillUnmount?(tag: Lifecycle.Key): void;
22
24
 
23
25
  componentDidMount?(): void;
24
26
  componentWillRender?(): void;
package/types/model.d.ts CHANGED
@@ -1,19 +1,12 @@
1
1
  import { Key } from 'react';
2
2
 
3
3
  import Lifecycle from './lifecycle';
4
- import { Select, Selector } from './selector';
5
- import { BunchOf, Callback, Class, InstanceOf, Query, RequestCallback, UpdateCallback } from './types';
6
-
7
- interface PropertyDescriptor<T> {
8
- configurable?: boolean;
9
- enumerable?: boolean;
10
- value?: T;
11
- writable?: boolean;
12
- get?(): T;
13
- set?(v: T): void;
14
- }
4
+ import { BunchOf, Class, InstanceOf } from './types';
15
5
 
6
+ type Callback = () => void;
16
7
  type Argument<T> = T extends (arg: infer U) => any ? U : never;
8
+ type IfApplicable<T extends {}, K> = K extends keyof T ? T[K] : undefined;
9
+ type Including<T> = T | (string & Record<never, never>);
17
10
 
18
11
  type Thenable<T> = {
19
12
  then(onFulfilled: (arg: T) => void): void;
@@ -26,17 +19,29 @@ export namespace Model {
26
19
  current: T | null;
27
20
  }
28
21
 
29
- type GetFunction<T> = (within?: Subscriber) => T;
22
+ type UpdateCallback<T, P> = (this: T, value: IfApplicable<T, P>, changed: P) => void;
23
+
24
+ type EffectCallback<T> = (this: T, argument: T) => Callback | Promise<any> | void;
30
25
 
31
26
  /**
32
27
  * Property initializer, will run upon instance creation.
33
28
  * Optional returned callback will run when once upon first access.
34
29
  */
35
30
  type Instruction<T> = (this: Controller, key: string, thisArg: Controller) =>
36
- void | GetFunction<T> | PropertyDescriptor<T>;
37
-
38
- /** Shallow replacement given all entries of Model */
39
- type Overlay<T, R> = { [K in keyof Entries<T>]: R };
31
+ void | Instruction.Getter<T> | Instruction.Descriptor<T>;
32
+
33
+ namespace Instruction {
34
+ interface Descriptor<T> {
35
+ configurable?: boolean;
36
+ enumerable?: boolean;
37
+ value?: T;
38
+ writable?: boolean;
39
+ get?(current: T | undefined, within?: Subscriber): T;
40
+ set?(value: T, state: any): boolean | void;
41
+ }
42
+
43
+ type Getter<T> = (state: T | undefined, within?: Subscriber) => T;
44
+ }
40
45
 
41
46
  /** Subset of `keyof T` excluding keys defined by base Model */
42
47
  type Fields<T, E = Model> = Exclude<keyof T, keyof E>;
@@ -52,87 +57,48 @@ export namespace Model {
52
57
  [P in K]: Value<T[P]>;
53
58
  }
54
59
 
55
- /** Object comperable to data which may be found in T. */
56
- type Data<T, E = Model> = Partial<Entries<T, E>>;
60
+ /** Object comperable to data found in T. */
61
+ type Compat<T, Exclude = Model> = Partial<Entries<T, Exclude>>;
57
62
 
58
63
  /** Subset of `keyof T` excluding keys defined by base Model, except lifecycle. */
59
64
  type Events<T> = Omit<T, Exclude<keyof Model, keyof Lifecycle>>;
60
65
 
61
- type EventsCompat<T> = keyof T | keyof Lifecycle;
62
-
63
- /**
64
- * Field selector which includes Model-Lifecycle events.
65
- * Can select for any tracked-property on a specified controller.
66
- *
67
- * Function `SelectEvent<T>` is a preferred alterative to string `keyof T`.
68
- *
69
- * ---
70
- *
71
- * ```js
72
- * Model.on(x => x.foo.bar.didMountComponent, cb)
73
- * ```
74
- * is equivalent to, while also more robust than:
75
- * ```js
76
- * Model.on(["foo", "bar", "didMountComponent"], cb)
77
- * ```
78
- */
79
- type SelectEvents<T> = Selector.Function<Events<T>>;
80
-
81
- /**
82
- * Field selector function you provide. Argument is a representation of controller specified.
83
- * *When used as an argument*, return a chain of properties desired for a given operation.
84
- *
85
- * Allows for refactor safe selection of properties belonging to a controller.
86
- * Using selectors is generally recommended to prevent unexpected behavior to be caused by bundling of your code.
87
- *
88
- * ---
89
- *
90
- * **Selector used to update specific properties:**
91
- *
92
- * ```js
93
- * Model.update(x => x.foo.bar.baz)
94
- * ```
95
- *
96
- * is equivalent to, while more robust than:
97
- *
98
- * ```js
99
- * Model.update(["foo", "bar", "baz"])
100
- * ```
101
- */
102
- type SelectFields<T> = Selector.Function<Omit<T, keyof Model>>;
103
-
104
- type SelectField<T> = (arg: Omit<T, keyof Model>) => any;
105
-
106
- type SelectFieldKey<T> = Select.Key<Fields<T>>;
66
+ type EventsCompat<T> = Including<keyof T | keyof Lifecycle>;
107
67
 
108
68
  type Typeof<T, ST, X extends keyof T = Exclude<keyof T, keyof Model>> = {
109
69
  [Key in X]: T[Key] extends ST ? Key : never;
110
70
  }[X];
111
71
 
112
- type SelectTypeof<T, ST> = Select.Key<Typeof<T, ST>>;
113
-
114
- type HandleValue = (value: any) => boolean | void;
115
-
116
72
  export namespace Controller {
117
- export type Listen = (key: string, source: Controller) =>
73
+ type RequestCallback = (keys: readonly string[]) => void;
74
+
75
+ type OnEvent = (key: string, source: Controller) =>
118
76
  RequestCallback | undefined;
77
+
78
+ type OnValue = <T>(this: T, value: any, state: T) => boolean | void;
119
79
  }
120
80
 
121
81
  export class Controller {
122
82
  state: BunchOf<any>;
123
83
  subject: {};
124
- waiting: Set<RequestCallback>;
84
+ waiting: Set<Controller.RequestCallback>;
85
+ frame: Set<string>;
125
86
 
126
- /** Add property to managed state. */
127
- manage(key: string, initial: any, effect?: HandleValue): void;
87
+ start(): this;
128
88
 
129
- select(using?: Query): string[];
89
+ manage(key: string, effect?: Controller.OnValue): void;
130
90
 
131
- setter(key: string, effect?: HandleValue): (value: any) => boolean | void;
91
+ setter(key: string, effect?: Controller.OnValue): (value: any) => boolean | void;
132
92
 
133
- addListener(listener: Controller.Listen): Callback;
93
+ addListener(listener: Controller.OnEvent): Callback;
134
94
 
135
95
  update(key: string, value?: any): void;
96
+
97
+ requestUpdate(): PromiseLike<readonly string[] | false>;
98
+ requestUpdate(strict: true): Promise<readonly string[]>;
99
+ requestUpdate(strict: false): Promise<false>;
100
+ requestUpdate(strict: boolean): Promise<readonly string[] | false>;
101
+ requestUpdate(callback: Controller.RequestCallback): void;
136
102
  }
137
103
 
138
104
  export class Subscriber {
@@ -140,13 +106,13 @@ export namespace Model {
140
106
  source: any;
141
107
  parent: Controller;
142
108
  active: boolean;
143
- listen: Controller.Listen;
109
+ listen: Controller.OnEvent;
144
110
  dependant: Set<{
145
111
  commit(): void;
146
112
  release(): void;
147
113
  }>;
148
114
 
149
- follow(key: string, cb?: RequestCallback | undefined): void;
115
+ follow(key: string, cb?: Controller.RequestCallback | undefined): void;
150
116
  commit(): Callback;
151
117
  release(): Callback;
152
118
  onUpdate(): void;
@@ -154,7 +120,7 @@ export namespace Model {
154
120
  }
155
121
 
156
122
  declare const CONTROL: unique symbol;
157
- declare const UPDATE: unique symbol;
123
+ declare const WHY: unique symbol;
158
124
  declare const LOCAL: unique symbol;
159
125
  declare const STATE: unique symbol;
160
126
 
@@ -175,7 +141,7 @@ export abstract class Model {
175
141
  * If accessed directly, will contain all keys from last push.
176
142
  * If within a subscribed function, will contain only keys which explicitly caused a refresh.
177
143
  **/
178
- [UPDATE]?: readonly string[];
144
+ [WHY]?: readonly string[];
179
145
 
180
146
  /**
181
147
  * Circular reference to `this` controller.
@@ -236,25 +202,19 @@ export abstract class Model {
236
202
  */
237
203
  set: this;
238
204
 
239
- import <O extends Model.Data<this>> (via: O, select?: string[] | Model.SelectFields<this>): void;
205
+ import <O extends Model.Compat<this>> (via: O, select?: string[]): void;
240
206
 
241
207
  export(): Model.State<this>;
242
208
  export <P extends Model.Fields<this>> (select: P[]): Model.State<this, P>;
243
- export <S extends Model.SelectFields<this>> (select: S): Model.State<this, Selector.From<S>>;
244
209
 
245
210
  update(): PromiseLike<readonly string[] | false>;
246
211
  update(strict: true): Promise<readonly string[]>;
247
212
  update(strict: false): Promise<false>;
248
213
  update(strict: boolean): Promise<readonly string[] | false>;
249
214
 
250
- update(keys: Model.Fields<this>): Thenable<readonly string[]>;
251
- update(keys: Model.SelectFieldKey<this>): Thenable<readonly string[]>;
252
-
253
- update(keys: Model.Fields<this>, callMethod: boolean): PromiseLike<readonly string[]>;
254
- update(keys: Model.SelectFields<this>, callMethod: boolean): PromiseLike<readonly string[]>;
255
-
256
- update<T>(keys: Model.Fields<this>, argument: T): PromiseLike<readonly string[]>;
257
- update<T>(keys: Model.SelectFields<this>, argument: T): PromiseLike<readonly string[]>;
215
+ update(keys: Including<Model.Fields<this>>): Thenable<readonly string[]>;
216
+ update(keys: Including<Model.Fields<this>>, callMethod: boolean): PromiseLike<readonly string[]>;
217
+ update<T>(keys: Including<Model.Fields<this>>, argument: T): PromiseLike<readonly string[]>;
258
218
 
259
219
  /*
260
220
  Issue with self-reference, using fallback.
@@ -289,48 +249,41 @@ export abstract class Model {
289
249
  tap(): this;
290
250
 
291
251
  /** Tracks specific key of this controller within a component. */
292
- tap <K extends Model.Fields<this>> (key: K, expect?: boolean): this[K];
293
252
  tap <K extends Model.Fields<this>> (key: K, expect: true): Exclude<this[K], undefined>;
253
+ tap <K extends Model.Fields<this>> (key: K, expect?: boolean): this[K];
294
254
 
295
- tap <T> (from: (this: this, state: this) => Promise<T>, expect?: boolean): T | undefined;
296
255
  tap <T> (from: (this: this, state: this) => Promise<T>, expect: true): Exclude<T, undefined>;
256
+ tap <T> (from: (this: this, state: this) => Promise<T>, expect?: boolean): T | undefined;
297
257
 
298
- tap <T> (from: (this: this, state: this) => T, expect?: boolean): T;
299
258
  tap <T> (from: (this: this, state: this) => T, expect: true): Exclude<T, undefined>;
259
+ tap <T> (from: (this: this, state: this) => T, expect?: boolean): T;
300
260
 
301
261
  // Keyed
302
- on <S extends Model.SelectEvents<this>> (via: S, cb: Selector.Callback<S, this>, squash?: false, once?: boolean): Callback;
303
- on <P = Model.EventsCompat<this>> (keys: [], listener: UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
304
- on <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
262
+ on <P = Model.EventsCompat<this>> (keys: [], listener: Model.UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
263
+ on <P extends Model.EventsCompat<this>> (key: P | P[], listener: Model.UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
305
264
  // Squash
306
- on <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true, once?: boolean): Callback;
307
265
  on <P = Model.EventsCompat<this>> (keys: [], listener: (keys: P[]) => void, squash: true, once?: boolean): Callback;
308
266
  on <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true, once?: boolean): Callback;
309
267
  // Unknown
310
- on <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean, once?: boolean): Callback;
311
268
  on (keys: [], listener: unknown, squash: boolean, once?: boolean): Callback;
312
269
  on <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean, once?: boolean): Callback;
313
270
 
314
271
  // Keyed
315
- once <S extends Model.SelectEvents<this>> (via: S, cb: Selector.Callback<S, this>, squash?: false): Callback;
316
- once <P = Model.EventsCompat<this>> (keys: [], listener: UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
317
- once <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false): Callback;
272
+ once <P = Model.EventsCompat<this>> (keys: [], listener: Model.UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
273
+ once <P extends Model.EventsCompat<this>> (key: P | P[], listener: Model.UpdateCallback<this, P>, squash?: false): Callback;
318
274
  // Squash
319
- once <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true): Callback;
320
275
  once <P = Model.EventsCompat<this>> (keys: [], listener: (keys: P[]) => void, squash: true, once?: boolean): Callback;
321
276
  once <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true): Callback;
322
277
  // Promise
323
- once <S extends Model.SelectEvents<this>> (via: S): Promise<Selector.From<S>[]>;
324
278
  once <P = Model.EventsCompat<this>> (keys: [], listener: (keys: P[]) => void, squash: true, once?: boolean): Callback;
325
279
  once <P extends Model.EventsCompat<this>> (key: P | P[]): Promise<P[]>;
326
280
  // Unknown
327
- once <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean): Callback;
328
281
  once (keys: [], listener: unknown, squash: boolean, once?: boolean): Callback;
329
282
  once <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean): Callback;
330
283
 
331
- effect(callback: (this: this, state: this) => void, select?: Model.SelectFields<this>): Callback;
332
- effect(callback: (this: this, state: this) => void, select?: []): Callback;
333
- effect(callback: (this: this, state: this) => void, select?: (keyof this)[]): Callback;
284
+ effect(callback: Model.EffectCallback<this>): Callback;
285
+ effect(callback: Model.EffectCallback<this>, select: []): Callback;
286
+ effect(callback: Model.EffectCallback<this>, select: (keyof this)[]): Callback;
334
287
 
335
288
  /**
336
289
  * **React Hook** - Attach to instance of this controller within a component.
@@ -369,7 +322,7 @@ export abstract class Model {
369
322
  static LOCAL: typeof LOCAL;
370
323
 
371
324
  /** Use symbol to access keys affected by last update. */
372
- static WHY: typeof UPDATE;
325
+ static WHY: typeof WHY;
373
326
 
374
327
  /**
375
328
  * Creates a new instance of this controller.
@@ -416,36 +369,25 @@ export abstract class Model {
416
369
  */
417
370
  static using <T extends Class, I extends InstanceOf<T>, D extends Partial<I>> (this: T, data: D, only?: (keyof D)[]): I;
418
371
 
419
- /**
420
- * **React Hook** - Locate most relevant instance of this type in context.
421
- */
422
- static find <T extends Class>(this: T, strict: true): InstanceOf<T>;
423
- static find <T extends Class>(this: T, strict?: boolean): InstanceOf<T> | undefined;
424
-
425
372
  /**
426
373
  * **React Hook** - Fetch most instance of this controller from context, if it exists.
427
374
  *
428
- * @param expect - If true, will throw where controller cannot be found. Otherwise, may return undefined.
375
+ * @param required - If false, may return undefined.
429
376
  */
430
- static get <T extends Class> (this: T, expect?: boolean): InstanceOf<T> | undefined;
377
+ static get <T extends Class> (this: T, required?: true): InstanceOf<T>;
431
378
 
432
379
  /**
433
380
  * **React Hook** - Fetch most instance of this controller from context.
434
381
  *
435
- * @param expect - Will throw if controller cannot be found.
382
+ * @param required - Unless false, will throw where instance cannot be found.
436
383
  */
437
- static get <T extends Class> (this: T, expect: true): InstanceOf<T>;
384
+ static get <T extends Class> (this: T, required: boolean): InstanceOf<T> | undefined;
438
385
 
439
386
  /**
440
387
  * **React Hook** - Fetch specific value from instance of this controller in context.
441
388
  */
442
389
  static get <T extends Class, I extends InstanceOf<T>, K extends Model.Fields<I>> (this: T, key: K): I[K];
443
390
 
444
- /**
445
- * **React Hook** - Fetch specific value from instance of this controller in context.
446
- */
447
- static get <T extends Class, I extends InstanceOf<T>, K extends Model.SelectField<I>> (this: T, key?: K): ReturnType<K>;
448
-
449
391
  /**
450
392
  * **React Hook** - Fetch and subscribe to instance of this controller within ambient component.
451
393
  */
@@ -454,19 +396,14 @@ export abstract class Model {
454
396
  /**
455
397
  * **React Hook** - Fetch and subscribe to a value on applicable instance within ambient component.
456
398
  */
399
+ static tap <T extends Class, I extends InstanceOf<T>, K extends Model.Fields<I>> (this: T, key: K, expect: true): Exclude<I[K], undefined>;
457
400
  static tap <T extends Class, I extends InstanceOf<T>, K extends Model.Fields<I>> (this: T, key: K, expect?: boolean): I[K];
458
- static tap <T, M extends Class, I extends InstanceOf<M>> (this: M, from: (this: I, state: I) => Promise<T>, expect?: boolean): T | undefined;
459
- static tap <T, M extends Class, I extends InstanceOf<M>> (this: M, from: (this: I, state: I) => T, expect?: boolean): T;
460
401
 
461
- /**
462
- * **React Hook** - Fetch and subscribe to a value on applicable instance within ambient component.
463
- *
464
- * **(In Expect Mode)** - Will throw of value is undefined.
465
- * This makes return type non-nullable and convenient to use without optional chaining.
466
- */
467
- static tap <T extends Class, I extends InstanceOf<T>, K extends Model.Fields<I>> (this: T, key: K, expect: true): Exclude<I[K], undefined>;
468
402
  static tap <T, M extends Class, I extends InstanceOf<M>> (this: M, from: (this: I, state: I) => Promise<T>, expect: true): Exclude<T, undefined>;
403
+ static tap <T, M extends Class, I extends InstanceOf<M>> (this: M, from: (this: I, state: I) => Promise<T>, expect?: boolean): T | undefined;
404
+
469
405
  static tap <T, M extends Class, I extends InstanceOf<M>> (this: M, from: (this: I, state: I) => T, expect: true): Exclude<T, undefined>;
406
+ static tap <T, M extends Class, I extends InstanceOf<M>> (this: M, from: (this: I, state: I) => T, expect?: boolean): T;
470
407
 
471
408
  /**
472
409
  * **React Hook** - Attach to instance of this controller within ambient component.
@@ -486,21 +423,16 @@ export abstract class Model {
486
423
  */
487
424
  static tag <T extends Class, I extends InstanceOf<T>> (this: T, idFactory: (on: I) => Key | void): I;
488
425
 
489
- /**
490
- * **React Hook** - Fetch and subscribe to *class itself* within a component.
491
- *
492
- * This allows you to do pretty meta stuff.
493
- *
494
- * Documentation TBD.
495
- */
496
426
  static meta <T extends Class>(this: T): T;
497
427
 
498
- /**
499
- * **React Hook** - Fetch and subscribe to value defined on class itself using selectors.
500
- *
501
- * Documentation TBD.
502
- */
503
- static meta <T extends Class, K extends Model.SelectField<T>> (this: T, key?: K): ReturnType<K>;
428
+ static meta <T extends Class, K extends keyof T> (this: T, key: K, expect: true): Exclude<T[K], undefined>;
429
+ static meta <T extends Class, K extends keyof T> (this: T, key: K, expect?: boolean): T[K];
430
+
431
+ static meta <T, M extends Class> (this: M, from: (this: M, state: M) => Promise<T>, expect: true): Exclude<T, undefined>;
432
+ static meta <T, M extends Class> (this: M, from: (this: M, state: M) => Promise<T>, expect?: boolean): T | undefined;
433
+
434
+ static meta <T, M extends Class> (this: M, from: (this: M, state: M) => T, expect: true): Exclude<T, undefined>;
435
+ static meta <T, M extends Class> (this: M, from: (this: M, state: M) => T, expect?: boolean): T;
504
436
 
505
437
  /**
506
438
  * Static equivalent of `x instanceof this`.
@@ -511,16 +443,13 @@ export abstract class Model {
511
443
  }
512
444
 
513
445
  export class Singleton extends Model {
514
- /** Get current instance of this singleton. Will throw if one does not exist. */
515
- static is<T extends Class>(this: T): InstanceOf<T>;
516
-
517
446
  /**
518
447
  * Update the active instance of this class.
519
448
  * Returns a thenable; resolves after successful update.
520
449
  * If instance does not already exist, one will be created.
521
450
  **/
522
- static update<T extends Class>(
523
- this: T, updates: Model.Data<InstanceOf<T>>
451
+ static set<T extends Class>(
452
+ this: T, updates: Model.Compat<InstanceOf<T>>
524
453
  ): PromiseLike<string[] | false>;
525
454
 
526
455
  /** Destroy current instance of Singleton, if it exists. */