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