@expressive/mvc 0.27.0 → 0.29.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,21 @@ 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
+ type OnValue<T, P extends Model.Key<T>> = (this: T, value: T[P], updated: Model.Event<T>[]) => void;
62
+ type OnValues<T, P extends Model.Key<T>> = (this: T, value: Model.Export<T, P>, updated: Model.Event<T>[]) => void;
63
+ interface Observable {
64
+ get(): Model.Export<this>;
65
+ get(effect: Model.Effect<this>): Callback;
66
+ get<P extends Model.Key<this>>(select: P): this[P];
67
+ get<P extends Model.Key<this>>(select: P, onUpdate: OnValue<this, P>, once?: boolean): Callback;
68
+ get<P extends Model.Key<this>>(select: P[]): Model.Export<this, P>;
69
+ get<P extends Model.Key<this>>(select: P[], onUpdate: OnValues<this, P>, once?: boolean): Callback;
70
+ set(): Promise<Model.Event<this>[]>;
71
+ set(timeout: number): Promise<Model.Event<this>[] | false>;
72
+ set<T extends Model.Values<this>>(source: T, only?: (keyof T)[]): Promise<Model.Event<T>[] | false>;
73
+ set<K extends Model.Key<this>>(key: K, value: Model.Value<this[K]>): Promise<Model.Event<this>[] | false>;
74
+ set<K extends Model.Event<this>>(key: K): Promise<Model.Event<this>[] | false>;
112
75
  }
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
76
 
169
77
  type InstanceOf<T> = T extends {
170
78
  prototype: infer U;
@@ -183,71 +91,37 @@ declare namespace Model {
183
91
  /**
184
92
  * Subset of `keyof T` which are not methods or defined by base Model U.
185
93
  **/
186
- type Key<T, U = Model> = Extract<Exclude<keyof T, keyof U | keyof Debug>, string>;
94
+ type Key<T, U = Model> = Extract<Exclude<keyof T, keyof U>, string>;
187
95
  /** Including but not limited to `keyof T` which are not methods or defined by base Model. */
188
96
  type Event<T> = Key<T> | (string & {});
189
97
  /** Actual value stored in state. */
190
- 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
- };
98
+ type Value<R> = R extends Ref<infer T> ? T : R extends Observable ? Export<R> : R;
200
99
  /** Object comperable to data found in T. */
201
- type Compat<T> = {
202
- [K in Key<T>]?: T[K];
100
+ type Values<T> = {
101
+ [P in Key<T>]?: Value<T[P]>;
203
102
  };
204
103
  /**
205
104
  * Values from current state of given controller.
206
105
  *
207
106
  * Differs from `Entries` as values here will drill into "real" values held by exotics like ref.
208
107
  */
209
- type Get<T, K extends Key<T> = Key<T>> = {
108
+ type Export<T, K extends Key<T> = Key<T>> = {
210
109
  [P in K]: Value<T[P]>;
211
110
  };
212
111
  /** Promise thrown by something which is not yet ready. */
213
112
  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
113
  /**
235
114
  * Reference to `this` without a subscription.
236
115
  * Use to obtain full reference from a destructure.
237
116
  */
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>;
117
+ type Focus<T> = T & {
118
+ is: T;
119
+ };
120
+ }
121
+ interface Model extends Observable {
122
+ }
123
+ declare class Model {
124
+ constructor(id?: string | number);
251
125
  /** Mark this instance for garbage collection. */
252
126
  null(): void;
253
127
  static get: typeof get$1;
@@ -265,7 +139,7 @@ declare class Model {
265
139
  *
266
140
  * Will determine if provided class is a subtype of this one.
267
141
  */
268
- static isTypeof<T extends Model.Type>(this: T, maybe: any): maybe is T;
142
+ static is<T extends Model.Type>(this: T, maybe: any): maybe is T;
269
143
  }
270
144
 
271
145
  declare namespace get {
@@ -376,27 +250,10 @@ declare function set<T>(value: T, onUpdate: set.Callback<T>): T;
376
250
 
377
251
  type Empty = Record<string, never>;
378
252
  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<{
253
+ type Record<T> = {
397
254
  [key: string | number]: T;
398
- }>;
399
- export {};
255
+ } & Observable;
256
+ type Object<T extends {}> = T & Observable;
400
257
  }
401
258
  /** Create a placeholder for specified Model type. */
402
259
  declare function use<T extends Model>(): T | undefined;
@@ -412,8 +269,135 @@ declare function use<T extends Model>(Type: Model.New<T>, ready?: (i: T) => void
412
269
  **/
413
270
  declare function use<T extends Model>(model: T, ready?: (i: T) => void): T;
414
271
  /** Create a managed record with observable entries. */
415
- declare function use<T = any, C = use.Collection<T>>(record: Empty, ready?: (object: C) => void): C;
272
+ declare function use<T = any, C = use.Record<T>>(record: Empty, ready?: (object: C) => void): C;
416
273
  /** Create a managed object with observable entries. */
417
- declare function use<T extends {}, O = use.Observable<T>>(data: T, ready?: (object: O) => void): O;
274
+ declare function use<T extends {}, O = use.Object<T>>(data: T, ready?: (object: O) => void): O;
275
+
276
+ declare namespace Context {
277
+ type Inputs = {
278
+ [key: string | number]: Model | Model.New;
279
+ };
280
+ }
281
+ declare class Context {
282
+ key: string;
283
+ private table;
284
+ private layer;
285
+ private has;
286
+ get<T extends Model>(Type: Model.Type<T>): T | undefined;
287
+ include(inputs: Context.Inputs): Map<Model, boolean>;
288
+ add<T extends Model>(input: T | Model.New<T>, implicit?: boolean): T;
289
+ push(): this;
290
+ pop(): void;
291
+ }
292
+
293
+ type Observer<T extends Model = any> = (key: Model.Event<T> | null | undefined, source: Control) => Callback | null | void;
294
+ declare namespace Control {
295
+ /**
296
+ * Property initializer, will run upon instance creation.
297
+ * Optional returned callback will run when once upon first access.
298
+ */
299
+ type Instruction<T> = (this: Control, key: string, thisArg: Control) => PropertyDescriptor<T> | Getter<T> | void;
300
+ type Getter<T> = (source: Model) => T;
301
+ type Setter<T> = (value: T) => boolean | void;
302
+ type PropertyDescriptor<T = any> = {
303
+ get?: Getter<T>;
304
+ set?: Setter<T> | false;
305
+ enumerable?: boolean;
306
+ value?: T;
307
+ };
308
+ type Callback = (control: Control) => void;
309
+ /**
310
+ * Callback for Controller.for() static method.
311
+ * Returned callback is forwarded.
312
+ */
313
+ type OnReady<T extends {}> = (control: Control<T>) => (() => void) | void;
314
+ type RequestRefresh = (update: (tick: number) => number) => void;
315
+ type GetContext = (target: Model) => (callback: (got: Context) => void) => void;
316
+ type GetAdapter<T> = (refresh: RequestRefresh, context: Context) => {
317
+ mount: () => (() => void) | void;
318
+ render: () => T;
319
+ } | void;
320
+ type GetHook = <T>(adapter: GetAdapter<T>) => T | null;
321
+ type UseAdapter<T extends Model, R> = (refresh: RequestRefresh) => {
322
+ instance: T;
323
+ mount: () => (() => void) | void;
324
+ render: R;
325
+ };
326
+ type UseHook = <T extends Model, R>(adapter: UseAdapter<T, R>) => R;
327
+ }
328
+ declare class Control<T extends {} = any> {
329
+ static ready: Set<Control.Callback>;
330
+ static after: Set<Callback>;
331
+ static before: Set<Callback>;
332
+ static pending: Set<Callback>;
333
+ static get: Control.GetHook;
334
+ static use: Control.UseHook;
335
+ static has: Control.GetContext;
336
+ static for: typeof control;
337
+ static apply: typeof apply;
338
+ static watch: typeof watch;
339
+ id?: string | number;
340
+ subject: T;
341
+ state: {
342
+ [key: string]: any;
343
+ };
344
+ latest?: Model.Event<T>[];
345
+ frame: Set<string>;
346
+ followers: Set<Observer<any>>;
347
+ observers: Map<string, Set<Observer<any>>>;
348
+ constructor(subject: T, id?: string | number | false);
349
+ add(key: Extract<keyof T, string>): void;
350
+ watch(key: string, output: Control.PropertyDescriptor<any>): void;
351
+ ref<K extends Model.Key<T>>(key: K, callback?: (this: T, value: T[K]) => boolean | void): (value: any) => void;
352
+ update(key: string): void;
353
+ addListener(fn: Observer): () => boolean;
354
+ clear(): void;
355
+ }
356
+ declare function control<T extends Model>(subject: T, ready: Control.OnReady<T>): Callback;
357
+ declare function control<T extends Model>(subject: T, ready?: boolean): Control<T>;
358
+ type Focus<T extends {}> = T & {
359
+ is: T;
360
+ };
361
+ declare function watch<T extends {}>(value: T, cb: Observer): Focus<T>;
362
+ declare function apply<T = any>(instruction: Control.Instruction<T>): T;
363
+
364
+ declare const STATE = "__state";
365
+ declare const UPDATE = "__update";
366
+ declare const CONTROL = "__control";
367
+ declare const PARENT = "__parent";
368
+ declare const Debug: {
369
+ /** Use to access snapshot of Model's current state. */
370
+ STATE: "__state";
371
+ /**
372
+ * Use to access snapshot of Model's latest update.
373
+ */
374
+ UPDATE: "__update";
375
+ /** Use to access a Model's controller. */
376
+ CONTROL: "__control";
377
+ /** Use to access a Model's parent, if exists. */
378
+ PARENT: "__parent";
379
+ };
380
+ /**
381
+ * Generic will declare debug properties on a given Model.
382
+ *
383
+ * These properties always exist at runtime, however are hidden unless you cast your Model as `Debug<T>`.
384
+ */
385
+ type Debug<T extends Model = Model> = T & {
386
+ /** Controller for this instance. */
387
+ [CONTROL]?: Control<T>;
388
+ /** Current state of this instance. */
389
+ [STATE]?: Model.Export<T>;
390
+ /**
391
+ * Last update causing a refresh to subscribers.
392
+ *
393
+ * If accessed directly, will contain all keys from last push.
394
+ * If within a subscribed function, will contain only keys which explicitly caused a refresh.
395
+ */
396
+ [UPDATE]?: readonly Model.Event<T>[];
397
+ /**
398
+ * Parent currently assigned to parent. Usually the model which this one is a property of.
399
+ */
400
+ [PARENT]?: Model;
401
+ };
418
402
 
419
403
  export { Context, Control, Debug, Model, Model as default, get, ref, run, set, use };