@expressive/mvc 0.71.0 → 0.72.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 CHANGED
@@ -6,9 +6,9 @@
6
6
  * - `false` - a normal update has completed.
7
7
  * - `true` - initial event; instance is ready.
8
8
  * - `null` - terminal event; instance is expired.
9
- * @param source - Instance of Model for which update has occured.
9
+ * @param source - Instance of State for which update has occured.
10
10
  */
11
- type OnUpdate<T extends Observable = any> = (this: T, key: Event, source: T) => (() => void) | null | void;
11
+ type Notify<T extends Observable = any> = (this: T, key: Event, source: T) => (() => void) | null | void;
12
12
  type Effect<T extends Observable> = (proxy: T) => ((update: boolean | null) => void) | Promise<void> | null | void;
13
13
  type Event = number | string | null | boolean | symbol;
14
14
  type PromiseLite<T = void> = {
@@ -21,61 +21,74 @@ interface Observable {
21
21
  [Observable](callback: Observable.Callback, required?: boolean): this | void;
22
22
  }
23
23
  declare const Observable: unique symbol;
24
- declare function addListener<T extends Observable>(subject: T, callback: OnUpdate<T>, select?: Event | Set<Event>): () => boolean;
24
+ declare function addListener<T extends Observable>(subject: T, callback: Notify<T>, select?: Event | Set<Event>): () => boolean;
25
25
  declare function event(subject: Observable, key?: string | number | symbol | null, silent?: boolean): void;
26
26
  /**
27
27
  * Create a side-effect which will update whenever values accessed change.
28
28
  * Callback is called immediately and whenever values are stale.
29
29
  *
30
- * @param target - Instance of Model to observe.
30
+ * @param target - Instance of State to observe.
31
31
  * @param callback - Function to invoke when values change.
32
32
  * @param requireValues - If `true` will throw if accessing a value which is `undefined`.
33
33
  */
34
- declare function createEffect<T extends Model>(target: T, callback: Effect<Required<T>>, requireValues: true): () => void;
35
- declare function createEffect<T extends Model>(target: T, callback: Effect<T>, recursive?: boolean): () => void;
34
+ declare function watch<T extends State>(target: T, callback: Effect<Required<T>>, requireValues: true): () => void;
35
+ declare function watch<T extends State>(target: T, callback: Effect<T>, recursive?: boolean): () => void;
36
36
 
37
37
  /** Reference bound instance methods to real ones. */
38
38
  declare const METHOD: WeakMap<any, any>;
39
- declare namespace Model {
40
- /** Any type of Model, using own class constructor as its identifier. */
41
- type Type<T extends Model = Model> = (abstract new (...args: any[]) => T) & typeof Model;
42
- /** A Model constructor, but which is not abstract. */
43
- type Init<T extends Model = Model> = (new (...args: Model.Args<T>) => T) & Omit<typeof Model, never>;
39
+ declare namespace State {
44
40
  /**
45
- * Model constructor callback - is called when Model finishes intializing.
46
- * Returned function will run when model is destroyed.
41
+ * State which is valid to create.
42
+ *
43
+ * This interface may be augmented to add dditional
44
+ * constraints on states, such as special hooks or properties,
45
+ * to interact with environment or helper frameworks.
46
+ **/
47
+ interface Valid extends State {
48
+ 'new'?(): void | (() => void);
49
+ }
50
+ /**
51
+ * A State class which is valid and may be instantiated.
47
52
  */
48
- type Callback<T extends Model = Model> = (this: T, thisArg: T) => Promise<void> | (() => void) | Assign<T> | void;
49
- /** Model constructor argument */
50
- type Argument<T extends Model = Model> = Assign<T> | Callback<T> | string | void;
51
- /** Model constructor arguments */
52
- type Args<T extends Model = any> = (Argument<T> | Args<T>)[];
53
- /** Subset of `keyof T` which are not methods or defined by base Model U. **/
54
- type Field<T> = Exclude<keyof T, keyof Model>;
55
- /** Any valid key for model, including but not limited to Field<T>. */
56
- type Event<T> = Field<T> | (string & {}) | number | symbol;
57
- /** Object overlay to override values and methods on a model. */
58
- type Assign<T> = {
53
+ type New<T extends State> = State.Class<T & Valid>;
54
+ /** Any type of State, using own class constructor as its identifier. */
55
+ type Extends<T extends State = State> = (abstract new (...args: any[]) => T) & typeof State;
56
+ /** A State constructor which is not abstract. */
57
+ type Class<T extends State = State> = (new (...args: State.Args<T>) => T) & Omit<typeof State, never>;
58
+ /** State constructor arguments */
59
+ type Args<T extends State = any> = (Args<T> | Init<T> | Assign<T> | string | void)[];
60
+ /**
61
+ * State constructor callback - is called when State finishes intializing.
62
+ * Returned function will run when state is destroyed.
63
+ */
64
+ type Init<T extends State = State> = (this: T, thisArg: T) => Promise<void> | (() => void) | Args<T> | Assign<T> | void;
65
+ /** Object overlay to override values and methods on a state. */
66
+ type Assign<T> = Record<string, unknown> & {
59
67
  [K in Field<T>]?: T[K] extends (...args: infer A) => infer R ? (this: T, ...args: A) => R : T[K];
60
- } & Record<string, unknown>;
61
- /** Export/Import compatible value for a given property in a Model. */
68
+ };
69
+ /** Subset of `keyof T` which are not methods or defined by base State U. **/
70
+ type Field<T> = Exclude<keyof T, keyof State>;
71
+ /** Any valid key for state, including but not limited to Field<T>. */
72
+ type Event<T> = Field<T> | number | symbol | (string & {});
73
+ /** Export/Import compatible value for a given property in a State. */
62
74
  type Export<R> = R extends {
63
75
  get(): infer T;
64
76
  } ? T : R;
65
- /** Value for a property managed by a model. */
66
- type Value<T extends Model, K extends Event<T>> = K extends keyof T ? Export<T[K]> : unknown;
67
- type OnEvent<T extends Model> = (this: T, key: unknown, source: T) => (() => void) | void | null;
68
- type OnUpdate<T extends Model, K extends Event<T>> = (this: T, key: K, thisArg: K) => void;
77
+ /** Value for a property managed by a state. */
78
+ type Value<T extends State, K extends Event<T>> = K extends keyof T ? Export<T[K]> : unknown;
79
+ type Setter<T> = (value: T, previous: T) => boolean | void | (() => T);
80
+ type OnEvent<T extends State> = (this: T, key: unknown, source: T) => void | (() => void) | null;
81
+ type OnUpdate<T extends State, K extends Event<T>> = (this: T, key: K, thisArg: K) => void;
69
82
  /**
70
- * Values from current state of given model.
83
+ * Values from current state of given state.
71
84
  * Differs from `Values` as values here will drill
72
85
  * into "real" values held by exotics like ref.Object.
73
86
  */
74
- type State<T> = {
87
+ type Values<T> = {
75
88
  [P in Field<T>]: Export<T[P]>;
76
89
  };
77
90
  /** Object comperable to data found in T. */
78
- type Values<T> = {
91
+ type Partial<T> = {
79
92
  [P in Field<T>]?: Export<T[P]>;
80
93
  };
81
94
  /** Exotic value, where actual value is contained within. */
@@ -86,7 +99,7 @@ declare namespace Model {
86
99
  /**
87
100
  * A callback function which is subscribed to parent and updates when accessed properties change.
88
101
  *
89
- * @param current - Current state of this model. This is a proxy which detects properties which
102
+ * @param current - Current state of this state. This is a proxy which detects properties which
90
103
  * where accessed, and thus depended upon to stay current.
91
104
  *
92
105
  * @param update - Set of properties which have changed, and events fired, since last update.
@@ -97,48 +110,35 @@ declare namespace Model {
97
110
  /**
98
111
  * A callback function returned by effect. Will be called when effect is stale.
99
112
  *
100
- * @param update - `true` if update is pending, `false` effect has been cancelled, `null` if model is destroyed.
101
- */
102
- type EffectCallback = ((update: boolean | null) => void);
103
- /**
104
- * Property initializer, will run upon instance creation.
105
- * Optional returned callback will run when once upon first access.
113
+ * @param update - `true` if update is pending, `false` effect has been cancelled, `null` if state is destroyed.
106
114
  */
107
- type Instruction<T = any, M extends Model = any> = (this: M, key: Extract<Field<M>, string>, thisArg: M, state: State<M>) => Descriptor<T> | ((source: M) => T) | void;
108
- type Getter<T> = (source: Model) => T;
109
- type Setter<T> = (value: T, previous: T) => boolean | void | (() => T);
110
- type Descriptor<T = any> = {
111
- get?: Getter<T> | boolean;
112
- set?: Setter<T> | boolean;
113
- enumerable?: boolean;
114
- value?: T;
115
- };
115
+ type EffectCallback = (update: boolean | null) => void;
116
116
  }
117
- interface Model {
117
+ interface State {
118
118
  /**
119
- * Loopback to instance of this model. This is useful when in a subscribed context,
119
+ * Loopback to instance of this state. This is useful when in a subscribed context,
120
120
  * to keep write access to `this` after a destructure. You can use it to read variables silently as well.
121
121
  **/
122
122
  is: this;
123
123
  }
124
- declare abstract class Model implements Observable {
125
- constructor(...args: Model.Args);
124
+ declare abstract class State implements Observable {
125
+ constructor(...args: State.Args);
126
126
  [Observable](callback: Observable.Callback, required?: boolean): this;
127
127
  /**
128
- * Pull current values from state. Flattens all models and exotic values recursively.
128
+ * Pull current values from state. Flattens all states and exotic values recursively.
129
129
  *
130
- * @returns Object with all values from this model.
130
+ * @returns Object with all values from this state.
131
131
  **/
132
- get(): Model.State<this>;
132
+ get(): State.Values<this>;
133
133
  /**
134
134
  * Run a function which will run automatically when accessed values change.
135
135
  *
136
136
  * @param effect Function to run, and again whenever accessed values change.
137
137
  * If effect returns a function, it will be called when a change occurs (syncronously),
138
- * effect is cancelled, or parent model is destroyed.
138
+ * effect is cancelled, or parent state is destroyed.
139
139
  * @returns Function to cancel listener.
140
140
  */
141
- get(effect: Model.Effect<this>): () => void;
141
+ get(effect: State.Effect<this>): () => void;
142
142
  /**
143
143
  * Get value of a property.
144
144
  *
@@ -146,7 +146,7 @@ declare abstract class Model implements Observable {
146
146
  * @param required - If true, will throw an error if property is not available.
147
147
  * @returns Value of property.
148
148
  */
149
- get<T extends Model.Event<this>>(key: T, required?: boolean): Model.Value<this, T>;
149
+ get<T extends State.Event<this>>(key: T, required?: boolean): State.Value<this, T>;
150
150
  /**
151
151
  * Run a function when a property is updated.
152
152
  *
@@ -154,18 +154,18 @@ declare abstract class Model implements Observable {
154
154
  * @param callback - Function to call when property is updated.
155
155
  * @returns Function to cancel listener.
156
156
  */
157
- get<T extends Model.Event<this>>(key: T, callback: Model.OnUpdate<this, T>): () => void;
157
+ get<T extends State.Event<this>>(key: T, callback: State.OnUpdate<this, T>): () => void;
158
158
  /**
159
- * Check if model is expired.
159
+ * Check if state is expired.
160
160
  *
161
- * @param status - `null` to check if model is expired.
162
- * @returns `true` if model is expired, `false` otherwise.
161
+ * @param status - `null` to check if state is expired.
162
+ * @returns `true` if state is expired, `false` otherwise.
163
163
  */
164
164
  get(status: null): boolean;
165
165
  /**
166
- * Callback when model is to be destroyed.
166
+ * Callback when state is to be destroyed.
167
167
  *
168
- * @param callback - Function to call when model is destroyed.
168
+ * @param callback - Function to call when state is destroyed.
169
169
  * @returns Function to cancel listener.
170
170
  */
171
171
  get(status: null, callback: () => void): () => void;
@@ -174,16 +174,16 @@ declare abstract class Model implements Observable {
174
174
  *
175
175
  * @returns Promise which resolves object with updated values, `undefined` if there no update is pending.
176
176
  **/
177
- set(): PromiseLike<Model.Event<this>[]> | undefined;
177
+ set(): PromiseLike<State.Event<this>[]> | undefined;
178
178
  /**
179
179
  * Update mulitple properties at once. Merges argument with current state.
180
- * Properties which are not managed by this model will be ignored.
180
+ * Properties which are not managed by this state will be ignored.
181
181
  *
182
182
  * @param assign - Object with properties to update.
183
183
  * @param silent - If an update does occur, listeners will not be refreshed automatically.
184
184
  * @returns Promise resolving an array of keys updated, `undefined` (immediately) if a noop.
185
185
  */
186
- set(assign?: Model.Assign<this>, silent?: boolean): PromiseLike<Model.Event<this>[]> | undefined;
186
+ set(assign?: State.Assign<this>, silent?: boolean): PromiseLike<State.Event<this>[]> | undefined;
187
187
  /**
188
188
  * Push an update. This will not change the value of associated property.
189
189
  *
@@ -198,7 +198,7 @@ declare abstract class Model implements Observable {
198
198
  * @param key - Property or event to dispatch.
199
199
  * @returns Promise resolves an array of keys updated.
200
200
  */
201
- set(key: Model.Event<this>): PromiseLike<Model.Event<this>[]>;
201
+ set(key: State.Event<this>): PromiseLike<State.Event<this>[]>;
202
202
  /**
203
203
  * Set a value for a property. This will update the value and notify listeners.
204
204
  *
@@ -211,10 +211,10 @@ declare abstract class Model implements Observable {
211
211
  *
212
212
  * @param key - Property to set value for.
213
213
  * @param value - Value to set for property.
214
- * @param init - If true, model will begin to manage the property if it is not already.
214
+ * @param init - If true, state will begin to manage the property if it is not already.
215
215
  * @returns Promise resolves an array of keys updated.
216
216
  */
217
- set(key: Model.Event<this>, value: unknown, init?: boolean): PromiseLike<Model.Event<this>[]>;
217
+ set(key: State.Event<this>, value: unknown, init?: boolean): PromiseLike<State.Event<this>[]>;
218
218
  /**
219
219
  * Call a function when update occurs.
220
220
  *
@@ -226,16 +226,16 @@ declare abstract class Model implements Observable {
226
226
  * @param callback - Function to call when update occurs.
227
227
  * @returns Function to remove listener. Will return `true` if removed, `false` if inactive already.
228
228
  *
229
- */
230
- set(callback: Model.OnEvent<this>): () => boolean;
229
+ */
230
+ set(callback: State.OnEvent<this>): () => boolean;
231
231
  /**
232
232
  * Call a function when a property is updated.
233
- * Unlike `get`, this calsl synchronously and will fire as many times as the property is updated.
233
+ * Unlike `get`, this calls synchronously and will fire as many times as the property is updated.
234
234
  *
235
235
  * @param callback - Function to call when property is updated.
236
236
  * @param event - Property to watch for updates.
237
237
  */
238
- set(callback: Model.OnEvent<this>, event: Model.Event<this> | null): () => boolean;
238
+ set(callback: State.OnEvent<this>, event: State.Event<this> | null): () => boolean;
239
239
  /**
240
240
  * Declare an end to updates. This event is final and will freeze state.
241
241
  * This event can be watched for as well, to run cleanup logic and internally will remove all listeners.
@@ -244,46 +244,60 @@ declare abstract class Model implements Observable {
244
244
  */
245
245
  set(status: null): void;
246
246
  /**
247
- * Iterate over managed properties in this instance of Model.
247
+ * Iterate over managed properties in this instance of State.
248
248
  * Yeilds the key and current value for each property.
249
249
  */
250
250
  [Symbol.iterator](): Iterator<[string, unknown]>;
251
251
  /**
252
- * Create and activate a new instance of this model.
252
+ * Create and activate a new instance of this state.
253
253
  *
254
254
  * **Important** - Unlike `new this(...)` - this method also activates state.
255
255
  *
256
256
  * @param args - arguments sent to constructor
257
257
  */
258
- static new<T extends Model>(this: Model.Init<T>, ...args: Model.Args<T>): T;
258
+ static new<T extends State>(this: State.New<T>, ...args: State.Args<T>): T;
259
259
  /**
260
260
  * Static equivalent of `x instanceof this`.
261
261
  * Determines if provided class is a subtype of this one.
262
262
  * If so, language server will make available all static
263
263
  * methods and properties of this class.
264
264
  */
265
- static is<T extends Model.Type>(this: T, maybe: unknown): maybe is T;
265
+ static is<T extends State.Extends>(this: T, maybe: unknown): maybe is T;
266
266
  /**
267
- * Register a callback to run when any instance of this Model is updated.
267
+ * Register a callback to run when any instance of this State is updated.
268
268
  */
269
- static on<T extends Model>(this: Model.Type<T>, listener: Model.OnEvent<T>): () => boolean;
269
+ static on<T extends State>(this: State.Extends<T>, listener: State.OnEvent<T>): () => boolean;
270
+ }
271
+
272
+ /**
273
+ * Property initializer, will run upon instance creation.
274
+ * Optional returned callback will run when once upon first access.
275
+ */
276
+ type Instruction<T = any, M extends State = any> = (this: M, key: Extract<State.Field<M>, string>, thisArg: M, state: State.Values<M>) => Instruction.Descriptor<T> | ((source: M) => T) | void;
277
+ declare namespace Instruction {
278
+ type Getter<T> = (source: State) => T;
279
+ type Descriptor<T = any> = {
280
+ get?: Getter<T> | boolean;
281
+ set?: State.Setter<T> | boolean;
282
+ enumerable?: boolean;
283
+ value?: T;
284
+ };
270
285
  }
286
+ declare function use<T>(instruction: Instruction<T>): T extends void ? unknown : T;
287
+ declare function use<T extends State>(Type: State.New<T>, required: false): T | undefined;
288
+ declare function use<T extends State>(Type: State.New<T>, ready?: (i: T) => void): T;
271
289
 
272
290
  declare namespace get {
273
- type Compute<T, S = any> = (on: S, key: string) => T;
274
- type Factory<T, S = any> = (this: S, key: string, thisArg: S) => T;
275
- type Source<T extends Model = Model> = (resolve: (x: T) => void) => void;
276
- type Effect<T> = (model: T, key: string) => (() => void) | void;
291
+ type Callback<T = any> = (state: T, subject: State) => void | boolean | (() => void);
277
292
  }
278
293
  /**
279
- * Fetches and assigns the controller which spawned this host.
280
- * When parent assigns an instance via `use()` directive, it
281
- * will be made available to child upon this request.
294
+ * Fetches upstream State from context with optional lifecycle callback.
295
+ * Callback runs on mount and can return cleanup function for unmount.
282
296
  *
283
- * @param Type - Type of controller compatible with this class.
284
- * @param expectParent - If true, will throw if Model is created without a parent.
297
+ * @param Type - Type of State to fetch.
298
+ * @param callback - Optional lifecycle callback, receives (state, subject). Can return cleanup function.
285
299
  */
286
- declare function get<T extends Model>(Type: Model.Type<T>, expectParent?: true): T;
300
+ declare function get<T extends State>(Type: State.Extends<T>, callback?: get.Callback<T>): T;
287
301
  /**
288
302
  * Fetches and assigns the controller which spawned this host.
289
303
  * When parent assigns an instance via `use()` directive, it
@@ -292,39 +306,90 @@ declare function get<T extends Model>(Type: Model.Type<T>, expectParent?: true):
292
306
  * @param Type - Type of controller compatible with this class.
293
307
  * @param required - If false, property may be undefined. Otherwise will throw suspense.
294
308
  */
295
- declare function get<T extends Model>(Type: Model.Type<T>, required?: false): T | undefined;
309
+ declare function get<T extends State>(Type: State.Extends<T>, required: false): T | undefined;
296
310
  /**
297
- * Implement a computed value from a foreign model. Output will be generated by provided function,
298
- * where the foreign model will be passed to that function.
311
+ * Collects downstream States, this will accumulate all instances of specified type for which this is an ancestor.
312
+ * Returns a frozen array that updates as States are added or removed.
313
+ * Callback runs on each State registration and can return cleanup or false to prevent registration.
299
314
  *
300
- * @param source - Type of Model to fetch for computation.
301
- * @param compute - Compute function. Will update automatically as input values change.
315
+ * @param Type - Type of State to collect.
316
+ * @param downstream - Must be true to enable downstream mode.
317
+ * @param callback - Optional lifecycle callback, receives (state, subject). May return false to prevent registration.
302
318
  */
303
- declare function get<T extends Model>(Type: Model.Type<T>, effect: get.Effect<T>): T;
319
+ declare function get<T extends State>(Type: State.Extends<T>, downstream: true, callback?: get.Callback<T>): readonly T[];
320
+
321
+ declare namespace set {
322
+ type Callback<T, S = any> = (this: S, next: T, previous: T) => ((next: T) => void) | Promise<any> | void | boolean;
323
+ type Compute<T, S = any> = (on: S, key: string) => T;
324
+ type Factory<T, S = any> = (this: S, key: string) => Promise<T> | T;
325
+ }
304
326
  /**
305
- * Implement a computed value; output will be generated by provided function.
327
+ * Set property as `undefined` but required.
306
328
  *
307
- * @param source - Source model from which computed value will be a subscriber.
308
- * @param compute - Compute function. Bound to a subscriber-proxy of source, returns output value. Will update automatically as input values change.
329
+ * Property cannot be accessed until it is defined. If accessed while undefined, a hybrid
330
+ * `Promise`/`Error` (aka: [Suspense](https://reactjs.org/docs/concurrent-mode-suspense.html)) will be thrown.
331
+ */
332
+ declare function set<T = any>(): T;
333
+ /**
334
+ * Set property with a factory function.
335
+ *
336
+ * **Note** Factory is lazy! It will only run if/when property is accessed.
337
+ * Value will be undefined until factory resolves, which will also dispatch an update for the property.
338
+ */
339
+ declare function set<T>(factory: set.Factory<T>, required: false): T | undefined;
340
+ /**
341
+ * Set property with a factory function.
342
+ *
343
+ * If async, property cannot be accessed until resolves, yeilding a result.
344
+ * If accessed while still processing, React Suspense will be thrown.
345
+ *
346
+ * @param factory - Callback run to derrive property value.
347
+ * @param required - If true run factory immediately on creation, otherwise on access.
348
+ */
349
+ declare function set<T>(factory: set.Factory<T>, required?: boolean): T;
350
+ /**
351
+ * Set property with a factory function.
352
+ *
353
+ * If async, property cannot be accessed until resolves, yeilding a result.
354
+ * If accessed while still processing, React Suspense will be thrown.
355
+ *
356
+ * @param factory - Callback run to derrive property value.
357
+ * @param onUpdate - Callback run when property is finished computing or is set.
358
+ */
359
+ declare function set<T>(factory: set.Factory<T>, onUpdate?: set.Callback<T>): T;
360
+ /**
361
+ * Set a property with empty placeholder and/or update callback.
362
+ *
363
+ * @param value - Starting value for property. If undefined, suspense will be thrown on access, until value is set and accepted by callback.
364
+ * @param onUpdate - Callback run when property is set. If returns false, update is not accepted and property will keep previous value.
309
365
  */
310
- declare function get<R, T extends Model>(source: T, compute: get.Compute<R, T>): R;
366
+ declare function set<T>(value: T | undefined, onUpdate?: set.Callback<T>): T;
311
367
  /**
312
- * Implement a computed value; output is returned by function from provided factory.
368
+ * Implement a reactive computed value using a method reference.
313
369
  *
314
- * Factory is bound to owner of property.
370
+ * The method will automatically re-run when any accessed properties change.
371
+ * Use `true` to indicate reactive mode with implicit `this` as the source.
315
372
  *
316
- * @param compute - Factory function to generate a getter to subscribe dependancies.
373
+ * @param reactiveToThis - Pass `true` to enable reactive mode with implicit this
374
+ * @param method - Method reference or compute function to use
375
+ */
376
+ declare function set<R, T = any>(reactiveToThis: true, method: set.Compute<R, T> | Function): R;
377
+ /**
378
+ * Implement a computed value; output will be generated by provided function.
379
+ *
380
+ * @param reactiveTo - Source state from which computed value will be a subscriber.
381
+ * @param compute - Compute function. Bound to a subscriber-proxy of source, returns output value. Will update automatically as input values change.
317
382
  */
318
- declare function get<R, T>(compute: get.Factory<R, T>): R;
383
+ declare function set<R, T extends State>(reactiveTo: T, compute: set.Compute<R, T>): R;
319
384
 
320
385
  declare namespace ref {
321
386
  type Callback<T> = (argument: T) => ((next: T | null) => void) | Promise<void> | void | boolean;
322
387
  interface Object<T = any> {
323
388
  /** Current value held by this reference. */
324
389
  current: T;
325
- /** Model instance this reference belongs to. */
326
- is: Model;
327
- /** Key of property on model this reference belongs to. */
390
+ /** State instance this reference belongs to. */
391
+ is: State;
392
+ /** Key of property on state this reference belongs to. */
328
393
  key: string;
329
394
  /**
330
395
  * Subscribe to changes of this reference.
@@ -338,13 +403,13 @@ declare namespace ref {
338
403
  }
339
404
  /** Object with references to all managed values of `T`. */
340
405
  /** Object with references to all managed values of `T`. */
341
- type Proxy<T extends Model> = {
342
- [P in Model.Field<T>]-?: Object<T[P]>;
406
+ type Proxy<T extends State> = {
407
+ [P in State.Field<T>]-?: Object<T[P]>;
343
408
  } & {
344
409
  get(): T;
345
410
  };
346
- type CustomProxy<T extends Model, R> = {
347
- [P in Model.Field<T>]-?: R;
411
+ type CustomProxy<T extends State, R> = {
412
+ [P in State.Field<T>]-?: R;
348
413
  } & {
349
414
  get(): T;
350
415
  };
@@ -355,18 +420,18 @@ declare namespace ref {
355
420
  *
356
421
  * *Properties are simultaneously a ref-function and ref-object, use as needed.*
357
422
  *
358
- * @param target - Source model from which to reference values.
423
+ * @param target - Source state from which to reference values.
359
424
  */
360
- declare function ref<T extends Model>(target: T): ref.Proxy<T>;
425
+ declare function ref<T extends State>(target: T): ref.Proxy<T>;
361
426
  /**
362
427
  * Creates an object with values based on managed values.
363
428
  * Each property will invoke mapper function on first access supply
364
429
  * the its return value going forward.
365
430
  *
366
- * @param target - Source model from which to reference values.
431
+ * @param target - Source state from which to reference values.
367
432
  * @param mapper - Function producing the placeholder value for any given property.
368
433
  */
369
- declare function ref<O extends Model, R>(target: O, mapper: (key: Model.Field<O>) => R): ref.CustomProxy<O, R>;
434
+ declare function ref<O extends State, R>(target: O, mapper: (key: State.Field<O>) => R): ref.CustomProxy<O, R>;
370
435
  /**
371
436
  * Creates a ref-compatible property.
372
437
  * Will persist value, and updates to this are made part of controller event-stream.
@@ -387,91 +452,61 @@ declare function ref<T>(callback?: ref.Callback<T>): ref.Object<T>;
387
452
  */
388
453
  declare function ref<T>(callback: ref.Callback<T | null>, ignoreNull: boolean): ref.Object<T>;
389
454
 
390
- declare namespace set {
391
- type Callback<T, S = any> = (this: S, next: T, previous: T) => ((next: T) => void) | Promise<any> | void | boolean;
392
- type Factory<T, S = any> = (this: S, key: string) => Thenable<T> | T;
393
- type Thenable<T> = {
394
- then: (onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any) => any;
395
- };
396
- }
397
- /**
398
- * Set property as `undefined` but required.
399
- *
400
- * Property cannot be accessed until it is defined. If accessed while undefined, a hybrid
401
- * `Promise`/`Error` (aka: [Suspense](https://reactjs.org/docs/concurrent-mode-suspense.html)) will be thrown.
402
- */
403
- declare function set<T = any>(): T;
404
- /**
405
- * Set property with a factory function.
406
- *
407
- * **Note** Factory is lazy! It will only run if/when property is accessed.
408
- * Value will be undefined until factory resolves, which will also dispatch an update for the property.
409
- */
410
- declare function set<T>(factory: set.Factory<T> | set.Thenable<T>, required: false): T | undefined;
411
- /**
412
- * Set property with a factory function.
413
- *
414
- * If async, property cannot be accessed until resolves, yeilding a result.
415
- * If accessed while still processing, React Suspense will be thrown.
416
- *
417
- * @param factory - Callback run to derrive property value.
418
- * @param required - If true run factory immediately on creation, otherwise on access.
419
- */
420
- declare function set<T>(factory: set.Factory<T> | set.Thenable<T>, required?: boolean): T;
421
- /**
422
- * Set property with a factory function.
423
- *
424
- * If async, property cannot be accessed until resolves, yeilding a result.
425
- * If accessed while still processing, React Suspense will be thrown.
426
- *
427
- * @param factory - Callback run to derrive property value.
428
- * @param onUpdate - Callback run when property is finished computing or is set.
429
- */
430
- declare function set<T>(factory: set.Factory<T> | set.Thenable<T>, onUpdate?: set.Callback<T>): T;
431
- /**
432
- * Set a property with empty placeholder and/or update callback.
433
- *
434
- * @param value - Starting value for property. If undefined, suspense will be thrown on access, until value is set and accepted by callback.
435
- * @param onUpdate - Callback run when property is set. If returns false, update is not accepted and property will keep previous value.
436
- */
437
- declare function set<T>(value: T | undefined, onUpdate?: set.Callback<T>): T;
438
-
439
- declare function use<T>(instruction: Model.Instruction<T>): T extends void ? unknown : T;
440
- declare function use<T extends Model>(Type: Model.Init<T>, required: false): T | undefined;
441
- declare function use<T extends Model>(Type: Model.Init<T>, ready?: (i: T) => void): T;
442
-
443
- declare namespace has {
444
- type Callback<T = any> = (model: T, recipient: Model) => void | boolean | (() => void);
445
- }
446
- declare function has<T extends Model>(type: Model.Type<T>, callback?: has.Callback<T>): readonly T[];
447
- declare function has(callback?: has.Callback): readonly Model[];
448
-
449
455
  declare namespace Context {
450
- type Multiple<T extends Model> = {
451
- [key: string | number]: Model.Init<T> | T;
456
+ type Multiple<T extends State> = {
457
+ [key: string | number]: State.Class<T> | T;
452
458
  };
453
- type Accept<T extends Model = Model> = T | Model.Init<T> | Multiple<T>;
454
- type Expect<T extends Model = Model> = (model: T) => (() => void) | void;
459
+ type Accept<T extends State = State> = T | State.Class<T> | Multiple<T>;
460
+ type Expect<T extends State = State> = (state: T) => (() => void) | void;
455
461
  }
456
462
  interface Context {
457
- [key: symbol]: Model | Context.Expect | null | undefined;
463
+ [key: symbol]: State | Context.Expect | null | undefined;
458
464
  }
459
465
  declare class Context {
460
- static get<T extends Model>(on: Model, callback: ((got: Context) => void)): void;
461
- static get<T extends Model>(on: Model): Context | undefined;
466
+ /**
467
+ * Get the context for a specified State. If a callback is provided, it will be run when
468
+ * the context becomes available.
469
+ */
470
+ static get<T extends State>(on: State, callback: (got: Context) => void): void;
471
+ /**
472
+ * Get the context for a specified State. Returns undefined if none are found.
473
+ */
474
+ static get<T extends State>(on: State): Context | undefined;
462
475
  id: string;
463
- protected layer: Map<string | number, Model | Model.Type<Model>>;
476
+ protected inputs: Record<string | number, State | State.Extends>;
464
477
  protected cleanup: Set<() => void>;
465
478
  constructor(inputs?: Context.Accept);
466
- /** Run callback when a specified type is registered to a **child** context. */
467
- has<T extends Model>(Type: Model.Type<T>, callback: (model: T) => void): void;
479
+ /** Find specified type registered to a parent context. Throws if none are found. */
480
+ get<T extends State>(Type: State.Extends<T>, require: true): T;
468
481
  /** Find specified type registered to a parent context. Returns undefined if none are found. */
469
- get<T extends Model>(Type: Model.Type<T>, require: true): T;
470
- get<T extends Model>(Type: Model.Type<T>, require?: boolean): T | undefined;
482
+ get<T extends State>(Type: State.Extends<T>, require?: boolean): T | undefined;
483
+ /** Run callback when a specified type is registered in context downstream. */
484
+ get<T extends State>(Type: State.Extends<T>, callback: (state: T) => void): () => void;
485
+ /**
486
+ * Adds a State to this context.
487
+ */
488
+ protected add<T extends State>(input: T | State.Class<T>, implicit?: boolean): T;
489
+ /**
490
+ * Register one or more States to this context.
491
+ *
492
+ * Context will add or remove States as needed to keep with provided input.
493
+ *
494
+ * @param inputs State, State class, or map of States / State classes to register.
495
+ * @param forEach Optional callback to run for each State registered.
496
+ */
497
+ use<T extends State>(inputs: Context.Accept<T>, forEach?: Context.Expect<T>): void;
498
+ /**
499
+ * Create a child context, optionally registering one or more States to it.
500
+ *
501
+ * @param inputs State, State class, or map of States / State classes to register.
502
+ */
471
503
  push(inputs?: Context.Accept): this;
504
+ /**
505
+ * Remove all States from this context.
506
+ *
507
+ * Will also run any cleanup callbacks registered when States were added.
508
+ */
472
509
  pop(): void;
473
- include<T extends Model>(inputs: Context.Accept<T>, forEach?: Context.Expect<T>): void;
474
- protected add<T extends Model>(input: T | Model.Init<T>, implicit?: boolean): T;
475
510
  }
476
511
 
477
- export { Context, METHOD, Model, Observable, addListener, createEffect, Model as default, event, get, has, ref, set, use };
512
+ export { Context, Instruction, METHOD, Observable, State, addListener, State as default, event, get, ref, set, use, watch };