@expressive/mvc 0.26.0 → 0.28.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/lib/index.d.ts CHANGED
@@ -16,22 +16,33 @@ declare function run<S>(action: Async<S>): typeof action & {
16
16
  active: boolean;
17
17
  };
18
18
 
19
- declare namespace Context {
20
- type Inputs = {
21
- [key: string | number]: Model | Model.New;
22
- };
23
- }
24
- declare class Context {
25
- key: string;
26
- private table;
27
- private layer;
28
- private has;
29
- get<T extends Model>(Type: Model.Type<T>): T | undefined;
30
- include(inputs: Context.Inputs): Map<Model, boolean>;
31
- add<T extends Model>(input: T | Model.New<T>, implicit?: boolean): T;
32
- push(): this;
33
- pop(): void;
34
- }
19
+ /** Type may not be undefined - instead will be null. */
20
+ type NoVoid<T> = T extends undefined | void ? null : T;
21
+ type ForceUpdate = {
22
+ /** Force an update in current component. */
23
+ (): void;
24
+ /**
25
+ * Force an update and again after promise either resolves or rejects.
26
+ * Will return a duplicate of given Promise, which resolves after refresh.
27
+ */
28
+ <T = void>(passthru: Promise<T>): Promise<T>;
29
+ /**
30
+ * Force a update while calling async function.
31
+ * A refresh will occur both before and after given function.
32
+ * Any actions performed before first `await` will occur before refresh!
33
+ */
34
+ <T = void>(invoke: () => Promise<T>): Promise<T>;
35
+ };
36
+ type Factory<T extends Model, R> = (this: T, current: T, update: ForceUpdate) => R;
37
+ /** Fetch instance of this class from context. */
38
+ declare function get$1<T extends Model>(this: Model.Type<T>, ignoreUpdates?: true): Model.Focus<T>;
39
+ /** Fetch instance of this class optionally. May be undefined, but will never subscribe. */
40
+ declare function get$1<T extends Model>(this: Model.Type<T>, required: boolean): Model.Focus<T> | undefined;
41
+ declare function get$1<T extends Model, R>(this: Model.Type<T>, factory: Factory<T, (() => R) | R | Promise<R>>): NoVoid<R>;
42
+ declare function get$1<T extends Model, R>(this: Model.Type<T>, factory: Factory<T, (() => R) | null>): NoVoid<R> | null;
43
+
44
+ declare function use$1<T extends Model>(this: Model.New<T>, callback?: (instance: T) => void, repeat?: boolean): Model.Focus<T>;
45
+ declare function use$1<T extends Model>(this: Model.New<T>, apply?: Model.Values<T>, repeat?: boolean): Model.Focus<T>;
35
46
 
36
47
  type Callback = () => void;
37
48
 
@@ -47,124 +58,19 @@ declare global {
47
58
  }
48
59
  }
49
60
 
50
- type Observer<T extends Model = any> = (key: Model.Event<T> | null | undefined, source: Control) => Callback | null | void;
51
- declare namespace Control {
52
- /**
53
- * Property initializer, will run upon instance creation.
54
- * Optional returned callback will run when once upon first access.
55
- */
56
- type Instruction<T> = (this: Control, key: string, thisArg: Control) => PropertyDescriptor<T> | Getter<T> | void;
57
- type Getter<T> = (source: Model) => T;
58
- type Setter<T> = (value: T) => boolean | void;
59
- type PropertyDescriptor<T = any> = {
60
- get?: Getter<T>;
61
- set?: Setter<T> | false;
62
- enumerable?: boolean;
63
- value?: T;
64
- };
65
- type Callback = (control: Control) => void;
66
- /**
67
- * Callback for Controller.for() static method.
68
- * Returned callback is forwarded.
69
- */
70
- type OnReady<T extends {}> = (control: Control<T>) => (() => void) | void;
71
- type RequestRefresh = (update: (tick: number) => number) => void;
72
- type GetContext = (target: Model) => (callback: (got: Context) => void) => void;
73
- type GetAdapter<T> = (refresh: RequestRefresh, context: Context) => {
74
- mount: () => (() => void) | void;
75
- render: () => T;
76
- } | void;
77
- type GetHook = <T>(adapter: GetAdapter<T>) => T | null;
78
- type UseAdapter<T extends Model, R> = (refresh: RequestRefresh) => {
79
- instance: T;
80
- mount: () => (() => void) | void;
81
- render: R;
82
- };
83
- type UseHook = <T extends Model, R>(adapter: UseAdapter<T, R>) => R;
84
- }
85
- declare class Control<T extends {} = any> {
86
- static ready: Set<Control.Callback>;
87
- static after: Set<Callback>;
88
- static before: Set<Callback>;
89
- static pending: Set<Callback>;
90
- static get: Control.GetHook;
91
- static use: Control.UseHook;
92
- static has: Control.GetContext;
93
- static for: typeof control;
94
- static apply: typeof apply;
95
- static watch: typeof watch;
96
- id: string | number;
97
- subject: T;
98
- state: {
99
- [key: string]: any;
100
- };
101
- latest?: Model.Event<T>[];
102
- frame: Set<string>;
103
- followers: Set<Observer<any>>;
104
- observers: Map<string, Set<Observer<any>>>;
105
- constructor(subject: T, id?: string | number);
106
- add(key: Extract<keyof T, string>): void;
107
- watch(key: Extract<keyof T, string>, output: Control.PropertyDescriptor<any>): void;
108
- ref<K extends Model.Key<T>>(key: K, callback?: (this: T, value: T[K]) => boolean | void): (value: any) => void;
109
- update(key: string): void;
110
- addListener(fn: Observer): () => boolean;
111
- clear(): void;
61
+ interface Observable {
62
+ get(): Model.Export<this>;
63
+ get(effect: Model.Effect<this>): Callback;
64
+ get<P extends Model.Key<this>>(select: P): this[P];
65
+ get<P extends Model.Key<this>>(select: Iterable<P>): Model.Export<this, P>;
66
+ get<P extends Model.Key<this>>(select: P, onUpdate: (this: this, value: this[P], updated: Model.Event<this>[]) => void, once?: boolean): Callback;
67
+ get<P extends Model.Key<this>>(select: Iterable<P>, onUpdate: (this: this, value: Model.Export<this, P>, updated: Model.Event<this>[]) => void, once?: boolean): Callback;
68
+ set(): Promise<Model.Event<this>[]>;
69
+ set(timeout: number): Promise<Model.Event<this>[] | false>;
70
+ set<T extends Model.Values<this>>(source: T, only?: (keyof T)[]): Promise<Model.Event<T>[] | false>;
71
+ set<K extends Model.Key<this>>(key: K, value: Model.Value<this[K]>): Promise<Model.Event<this>[] | false>;
72
+ set<K extends Model.Event<this>>(key: K): Promise<Model.Event<this>[] | false>;
112
73
  }
113
- declare function control<T extends Model>(subject: T, ready: Control.OnReady<T>): Callback;
114
- declare function control<T extends Model>(subject: T, ready?: boolean): Control<T>;
115
- declare function watch<T extends {}>(on: T, cb: Observer): T;
116
- declare function apply<T = any>(instruction: Control.Instruction<T>): T;
117
-
118
- declare const STATE = "__state";
119
- declare const UPDATE = "__update";
120
- declare const CONTROL = "__control";
121
- declare const PARENT = "__parent";
122
- declare const Debug: {
123
- /** Use to access snapshot of Model's current state. */
124
- STATE: "__state";
125
- /**
126
- * Use to access snapshot of Model's latest update.
127
- */
128
- UPDATE: "__update";
129
- /** Use to access a Model's controller. */
130
- CONTROL: "__control";
131
- /** Use to access a Model's parent, if exists. */
132
- PARENT: "__parent";
133
- };
134
- /**
135
- * Generic will declare debug properties on a given Model.
136
- *
137
- * These properties always exist at runtime, however are hidden unless you cast your Model as `Debug<T>`.
138
- */
139
- type Debug<T extends Model = Model> = T & {
140
- /** Controller for this instance. */
141
- [CONTROL]?: Control<T>;
142
- /** Current state of this instance. */
143
- [STATE]?: Model.Export<T>;
144
- /**
145
- * Last update causing a refresh to subscribers.
146
- *
147
- * If accessed directly, will contain all keys from last push.
148
- * If within a subscribed function, will contain only keys which explicitly caused a refresh.
149
- */
150
- [UPDATE]?: readonly Model.Event<T>[];
151
- /**
152
- * Parent currently assigned to parent. Usually the model which this one is a property of.
153
- */
154
- [PARENT]?: Model;
155
- };
156
-
157
- /** Type may not be undefined - instead will be null. */
158
- type NoVoid<T> = T extends undefined | void ? null : T;
159
- /** Fetch instance of this class from context. */
160
- declare function get$1<T extends Model>(this: Model.Type<T>, ignoreUpdates?: true): T;
161
- /** Fetch instance of this class optionally. May be undefined, but will never subscribe. */
162
- declare function get$1<T extends Model>(this: Model.Type<T>, required: boolean): T | undefined;
163
- declare function get$1<T extends Model, R>(this: Model.Type<T>, factory: Model.GetCallback<T, (() => R) | R | Promise<R>>): NoVoid<R>;
164
- declare function get$1<T extends Model, R>(this: Model.Type<T>, factory: Model.GetCallback<T, (() => R) | null>): NoVoid<R> | null;
165
-
166
- declare function use$1<T extends Model>(this: Model.New<T>, callback?: (instance: T) => void, repeat?: boolean): T;
167
- declare function use$1<T extends Model>(this: Model.New<T>, apply?: Model.Compat<T>, repeat?: boolean): T;
168
74
 
169
75
  type InstanceOf<T> = T extends {
170
76
  prototype: infer U;
@@ -183,71 +89,37 @@ declare namespace Model {
183
89
  /**
184
90
  * Subset of `keyof T` which are not methods or defined by base Model U.
185
91
  **/
186
- type Key<T, U = Model> = Extract<Exclude<keyof T, keyof U | keyof Debug>, string>;
92
+ type Key<T, U = Model> = Extract<Exclude<keyof T, keyof U>, string>;
187
93
  /** Including but not limited to `keyof T` which are not methods or defined by base Model. */
188
94
  type Event<T> = Key<T> | (string & {});
189
95
  /** Actual value stored in state. */
190
96
  type Value<R> = R extends Ref<infer T> ? T : R;
191
- /** Actual value belonging to a managed property. */
192
- type ValueOf<T extends {}, K> = K extends keyof T ? Value<T[K]> : undefined;
193
- type Export<T> = {
194
- [P in Key<T>]: Value<T[P]>;
195
- };
196
- /** Object containing managed entries found in T. */
197
- type Entries<T> = {
198
- [K in Key<T>]: T[K];
199
- };
200
97
  /** Object comperable to data found in T. */
201
- type Compat<T> = {
202
- [K in Key<T>]?: T[K];
98
+ type Values<T> = {
99
+ [P in Key<T>]?: Value<T[P]>;
203
100
  };
204
101
  /**
205
102
  * Values from current state of given controller.
206
103
  *
207
104
  * Differs from `Entries` as values here will drill into "real" values held by exotics like ref.
208
105
  */
209
- type Get<T, K extends Key<T> = Key<T>> = {
106
+ type Export<T, K extends Key<T> = Key<T>> = {
210
107
  [P in K]: Value<T[P]>;
211
108
  };
212
109
  /** Promise thrown by something which is not yet ready. */
213
110
  type Suspense = Promise<void> & Error;
214
- type OnCallback<T extends Model> = (this: T, keys: Model.Event<T>[] | null) => void;
215
- type GetCallback<T extends Model, R> = (this: T, model: T, update: ForceUpdate) => R;
216
- type ForceUpdate = {
217
- /** Force an update in current component. */
218
- (): void;
219
- /**
220
- * Force an update and again after promise either resolves or rejects.
221
- * Will return a duplicate of given Promise, which resolves after refresh.
222
- */
223
- <T = void>(passthru: Promise<T>): Promise<T>;
224
- /**
225
- * Force a update while calling async function.
226
- * A refresh will occur both before and after given function.
227
- * Any actions performed before first `await` will occur before refresh!
228
- */
229
- <T = void>(invoke: () => Promise<T>): Promise<T>;
230
- };
231
- }
232
- declare class Model {
233
- constructor(id?: string | number);
234
111
  /**
235
112
  * Reference to `this` without a subscription.
236
113
  * Use to obtain full reference from a destructure.
237
114
  */
238
- get is(): this;
239
- on(): Promise<Model.Event<this>[]>;
240
- on(timeout?: number): Promise<Model.Event<this>[] | false>;
241
- on<P extends Model.Event<this>>(keys?: P | P[], timeout?: number): Promise<P[] | false>;
242
- on<P extends Model.Event<this>>(keys: P | P[], listener: Model.OnCallback<this>, once?: boolean): Callback;
243
- on(effect: Model.Effect<this>): Callback;
244
- get(): Model.Export<this>;
245
- get<P extends Model.Key<this>>(select: P): this[P];
246
- get<P extends Model.Key<this>>(select: Iterable<P>): Model.Get<this, P>;
247
- get<P extends Model.Key<this>>(select: P, listener: (this: this, value: this[P]) => void): Callback;
248
- get<P extends Model.Key<this>>(select: Iterable<P>, listener: (this: this, value: Model.Get<this, P>) => void): Callback;
249
- set<T extends Model.Compat<this>>(source: T, only?: (keyof T)[]): Promise<Model.Key<T>[]>;
250
- set<K extends Model.Event<this>>(key: K, value?: Model.ValueOf<this, K>): Promise<Model.Event<this>[] | false>;
115
+ type Focus<T> = T & {
116
+ is: T;
117
+ };
118
+ }
119
+ interface Model extends Observable {
120
+ }
121
+ declare class Model {
122
+ constructor(id?: string | number);
251
123
  /** Mark this instance for garbage collection. */
252
124
  null(): void;
253
125
  static get: typeof get$1;
@@ -376,27 +248,10 @@ declare function set<T>(value: T, onUpdate: set.Callback<T>): T;
376
248
 
377
249
  type Empty = Record<string, never>;
378
250
  declare namespace use {
379
- type Key<T extends {}> = Extract<keyof T, string>;
380
- /**
381
- * Assign value to observable property.
382
- *
383
- * If property is not already observed, it will become so.
384
- */
385
- type SetValue<T extends {}> = <K extends Key<T>>(property: K, value: T[K]) => void;
386
- /**
387
- * Observe property for updates.
388
- *
389
- * If property is not already observed, it will become so.
390
- */
391
- type OnUpdate<T extends {}> = <K extends Key<T>>(property: K, callback: (value: T[K], key: K) => void) => () => void;
392
- export type Observable<T extends {}> = T & {
393
- set: SetValue<T>;
394
- on: OnUpdate<T>;
395
- };
396
- export type Collection<T> = Observable<{
251
+ type Record<T> = {
397
252
  [key: string | number]: T;
398
- }>;
399
- export {};
253
+ } & Observable;
254
+ type Object<T extends {}> = T & Observable;
400
255
  }
401
256
  /** Create a placeholder for specified Model type. */
402
257
  declare function use<T extends Model>(): T | undefined;
@@ -412,8 +267,135 @@ declare function use<T extends Model>(Type: Model.New<T>, ready?: (i: T) => void
412
267
  **/
413
268
  declare function use<T extends Model>(model: T, ready?: (i: T) => void): T;
414
269
  /** Create a managed record with observable entries. */
415
- declare function use<T = any, C = use.Collection<T>>(record: Empty, ready?: (object: C) => void): C;
270
+ declare function use<T = any, C = use.Record<T>>(record: Empty, ready?: (object: C) => void): C;
416
271
  /** Create a managed object with observable entries. */
417
- declare function use<T extends {}, O = use.Observable<T>>(data: T, ready?: (object: O) => void): O;
272
+ declare function use<T extends {}, O = use.Object<T>>(data: T, ready?: (object: O) => void): O;
273
+
274
+ declare namespace Context {
275
+ type Inputs = {
276
+ [key: string | number]: Model | Model.New;
277
+ };
278
+ }
279
+ declare class Context {
280
+ key: string;
281
+ private table;
282
+ private layer;
283
+ private has;
284
+ get<T extends Model>(Type: Model.Type<T>): T | undefined;
285
+ include(inputs: Context.Inputs): Map<Model, boolean>;
286
+ add<T extends Model>(input: T | Model.New<T>, implicit?: boolean): T;
287
+ push(): this;
288
+ pop(): void;
289
+ }
290
+
291
+ type Observer<T extends Model = any> = (key: Model.Event<T> | null | undefined, source: Control) => Callback | null | void;
292
+ declare namespace Control {
293
+ /**
294
+ * Property initializer, will run upon instance creation.
295
+ * Optional returned callback will run when once upon first access.
296
+ */
297
+ type Instruction<T> = (this: Control, key: string, thisArg: Control) => PropertyDescriptor<T> | Getter<T> | void;
298
+ type Getter<T> = (source: Model) => T;
299
+ type Setter<T> = (value: T) => boolean | void;
300
+ type PropertyDescriptor<T = any> = {
301
+ get?: Getter<T>;
302
+ set?: Setter<T> | false;
303
+ enumerable?: boolean;
304
+ value?: T;
305
+ };
306
+ type Callback = (control: Control) => void;
307
+ /**
308
+ * Callback for Controller.for() static method.
309
+ * Returned callback is forwarded.
310
+ */
311
+ type OnReady<T extends {}> = (control: Control<T>) => (() => void) | void;
312
+ type RequestRefresh = (update: (tick: number) => number) => void;
313
+ type GetContext = (target: Model) => (callback: (got: Context) => void) => void;
314
+ type GetAdapter<T> = (refresh: RequestRefresh, context: Context) => {
315
+ mount: () => (() => void) | void;
316
+ render: () => T;
317
+ } | void;
318
+ type GetHook = <T>(adapter: GetAdapter<T>) => T | null;
319
+ type UseAdapter<T extends Model, R> = (refresh: RequestRefresh) => {
320
+ instance: T;
321
+ mount: () => (() => void) | void;
322
+ render: R;
323
+ };
324
+ type UseHook = <T extends Model, R>(adapter: UseAdapter<T, R>) => R;
325
+ }
326
+ declare class Control<T extends {} = any> {
327
+ static ready: Set<Control.Callback>;
328
+ static after: Set<Callback>;
329
+ static before: Set<Callback>;
330
+ static pending: Set<Callback>;
331
+ static get: Control.GetHook;
332
+ static use: Control.UseHook;
333
+ static has: Control.GetContext;
334
+ static for: typeof control;
335
+ static apply: typeof apply;
336
+ static watch: typeof watch;
337
+ id?: string | number;
338
+ subject: T;
339
+ state: {
340
+ [key: string]: any;
341
+ };
342
+ latest?: Model.Event<T>[];
343
+ frame: Set<string>;
344
+ followers: Set<Observer<any>>;
345
+ observers: Map<string, Set<Observer<any>>>;
346
+ constructor(subject: T, id?: string | number | false);
347
+ add(key: Extract<keyof T, string>): void;
348
+ watch(key: string, output: Control.PropertyDescriptor<any>): void;
349
+ ref<K extends Model.Key<T>>(key: K, callback?: (this: T, value: T[K]) => boolean | void): (value: any) => void;
350
+ update(key: string): void;
351
+ addListener(fn: Observer): () => boolean;
352
+ clear(): void;
353
+ }
354
+ declare function control<T extends Model>(subject: T, ready: Control.OnReady<T>): Callback;
355
+ declare function control<T extends Model>(subject: T, ready?: boolean): Control<T>;
356
+ type Focus<T extends {}> = T & {
357
+ is: T;
358
+ };
359
+ declare function watch<T extends {}>(value: T, cb: Observer): Focus<T>;
360
+ declare function apply<T = any>(instruction: Control.Instruction<T>): T;
361
+
362
+ declare const STATE = "__state";
363
+ declare const UPDATE = "__update";
364
+ declare const CONTROL = "__control";
365
+ declare const PARENT = "__parent";
366
+ declare const Debug: {
367
+ /** Use to access snapshot of Model's current state. */
368
+ STATE: "__state";
369
+ /**
370
+ * Use to access snapshot of Model's latest update.
371
+ */
372
+ UPDATE: "__update";
373
+ /** Use to access a Model's controller. */
374
+ CONTROL: "__control";
375
+ /** Use to access a Model's parent, if exists. */
376
+ PARENT: "__parent";
377
+ };
378
+ /**
379
+ * Generic will declare debug properties on a given Model.
380
+ *
381
+ * These properties always exist at runtime, however are hidden unless you cast your Model as `Debug<T>`.
382
+ */
383
+ type Debug<T extends Model = Model> = T & {
384
+ /** Controller for this instance. */
385
+ [CONTROL]?: Control<T>;
386
+ /** Current state of this instance. */
387
+ [STATE]?: Model.Export<T>;
388
+ /**
389
+ * Last update causing a refresh to subscribers.
390
+ *
391
+ * If accessed directly, will contain all keys from last push.
392
+ * If within a subscribed function, will contain only keys which explicitly caused a refresh.
393
+ */
394
+ [UPDATE]?: readonly Model.Event<T>[];
395
+ /**
396
+ * Parent currently assigned to parent. Usually the model which this one is a property of.
397
+ */
398
+ [PARENT]?: Model;
399
+ };
418
400
 
419
401
  export { Context, Control, Debug, Model, Model as default, get, ref, run, set, use };