@expressive/mvc 0.17.1 → 0.18.1

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
@@ -1,46 +1,3 @@
1
- import React from 'react';
2
-
3
- type Callback = () => void;
4
- type Class = new (...args: any[]) => any;
5
- type InstanceOf<T> = T extends { prototype: infer U } ? U : never;
6
-
7
- /** Type may not be undefined - instead will be null. */
8
- type NoVoid<T> = T extends undefined ? null : T;
9
-
10
- type OptionalValues<T extends {}> = {
11
- [P in Model.Key<T>]: T[P] | undefined;
12
- }
13
-
14
- type NonOptionalValues<T extends {}> = {
15
- [P in Model.Key<T>]: Exclude<T[P], undefined>;
16
- };
17
-
18
- type Listener = {
19
- commit(): void;
20
- release(): void;
21
- };
22
- declare namespace Subscriber {
23
- type OnEvent<T = any> = (key: Model.Event<T> | null, source: Control) => Callback | void;
24
- }
25
- declare class Subscriber<T extends {} = any> {
26
- parent: Control<T>;
27
- onUpdate: Subscriber.OnEvent;
28
- strict?: boolean | undefined;
29
- proxy: T;
30
- clear: () => void;
31
- latest?: Model.Event<T>[];
32
- active: boolean;
33
- dependant: Set<Listener>;
34
- watch: Map<any, boolean | (() => boolean | void)>;
35
- constructor(parent: Control<T>, onUpdate: Subscriber.OnEvent, strict?: boolean | undefined);
36
- get using(): Model.Key<T>[];
37
- apply(values: Model.Compat<T>, keys?: Model.Key<T>[]): void;
38
- follow(key: any, value?: boolean | (() => boolean | void)): void;
39
- commit(): void;
40
- release(): void;
41
- private notify;
42
- }
43
-
44
1
  declare const LOCAL = "$debug local";
45
2
  declare const STATE = "$debug state";
46
3
  declare const UPDATE = "$debug update";
@@ -51,7 +8,7 @@ declare const Debug: {
51
8
  readonly STATE: "$debug state";
52
9
  readonly UPDATE: "$debug update";
53
10
  };
54
- type Debug<T extends {}> = T & {
11
+ type Debug<T extends Model> = T & {
55
12
  /** Controller for this instance. */
56
13
  [CONTROL]?: Control<T>;
57
14
  /** Current subscriber (if present) while used in a live context (e.g. hook or effect). */
@@ -67,6 +24,21 @@ type Debug<T extends {}> = T & {
67
24
  [UPDATE]?: readonly Model.Event<T>[];
68
25
  };
69
26
 
27
+ type Callback = () => void;
28
+ type Class = new (...args: any[]) => any;
29
+ type InstanceOf<T> = T extends { prototype: infer U } ? U : never;
30
+
31
+ /** Type may not be undefined - instead will be null. */
32
+ type NoVoid<T> = T extends undefined ? null : T;
33
+
34
+ type OptionalValues<T extends {}> = {
35
+ [P in Model.Key<T>]: T[P] | undefined;
36
+ }
37
+
38
+ type NonOptionalValues<T extends {}> = {
39
+ [P in Model.Key<T>]: Exclude<T[P], undefined>;
40
+ };
41
+
70
42
  declare namespace Model {
71
43
  export { Control };
72
44
  export { Subscriber };
@@ -86,7 +58,7 @@ declare namespace Model {
86
58
  export type Methods<T> = {
87
59
  [K in keyof T]: T[K] extends Ref ? never : T[K] extends Function ? K : never;
88
60
  }[keyof T];
89
- type BuiltIn = keyof Model | keyof Debug<{}>;
61
+ type BuiltIn = keyof Model | keyof Debug<Model>;
90
62
  /**
91
63
  * Subset of `keyof T` which are not methods or defined by base Model U.
92
64
  *
@@ -123,12 +95,28 @@ declare namespace Model {
123
95
  [P in Key<T>]: Value<T[P]>;
124
96
  };
125
97
  export type FindFunction = <T extends Model>(type: Model.Type<T>, relativeTo: Model, required: boolean) => (_refresh: (x: T) => void) => T | undefined;
98
+ export type TapCallback<T extends Model, R> = (this: T, model: T, update: ForceUpdate) => R;
99
+ type ForceUpdate = {
100
+ /** Force an update in current component. */
101
+ (): void;
102
+ /**
103
+ * Force an update and again after promise either resolves or rejects.
104
+ * Will return a duplicate of given Promise, which resolves after refresh.
105
+ */
106
+ <T = void>(passthru?: Promise<T>): Promise<T>;
107
+ /**
108
+ * Force a update while calling async function.
109
+ * A refresh will occur both before and after given function.
110
+ * Any actions performed before first `await` will occur before refresh!
111
+ */
112
+ <T = void>(invoke?: () => Promise<T>): Promise<T>;
113
+ };
114
+ export type Suspense = Promise<void> & Error;
126
115
  }
127
116
  declare class Model {
128
117
  /**
129
- * Circular reference to `this` controller.
130
- *
131
- * Useful to obtain full reference where one has already destructured.
118
+ * Reference to `this` without a subscription.
119
+ * Use to obtain full reference from a destructure.
132
120
  */
133
121
  is: this;
134
122
  constructor();
@@ -156,10 +144,8 @@ declare class Model {
156
144
  set<K extends Model.Event<this>>(key: Model.Event<this>, value: Model.ValueOf<this, K>): PromiseLike<readonly Model.Event<this>[]>;
157
145
  set<T extends Model.Compat<this>>(source: T, select: (keyof T)[]): PromiseLike<(keyof T)[]>;
158
146
  set<T extends Model.Compat<this>>(source: T, force?: boolean): PromiseLike<(keyof T)[]>;
159
- /**
160
- * Clean up side effects and mark this instance for garbage-collection.
161
- */
162
- end(): void;
147
+ /** Mark this instance for garbage collection. */
148
+ gc(): void;
163
149
  /**
164
150
  * Creates a new instance of this controller.
165
151
  *
@@ -168,6 +154,29 @@ declare class Model {
168
154
  * @param args - arguments sent to constructor
169
155
  */
170
156
  static new<T extends Class>(this: T, ...args: ConstructorParameters<T>): InstanceOf<T>;
157
+ static use<I extends Model>(this: Model.Type<I>, watch: Model.Key<I>[], callback?: (instance: I) => void): I;
158
+ static use<I extends Model>(this: Model.Type<I>, callback?: (instance: I) => void): I;
159
+ static use<I extends Model>(this: Model.Type<I>, apply: Model.Compat<I>, keys?: Model.Event<I>[]): I;
160
+ static get<T extends Model>(this: Model.Type<T>, required?: boolean): T;
161
+ static get<T extends Model>(this: Model.Type<T>, required: false): T | undefined;
162
+ static tap<T extends Model>(this: Model.Type<T>): T;
163
+ static tap<T extends Model, R extends readonly unknown[] | []>(this: Model.Type<T>, compute: Model.TapCallback<T, R | (() => R)>, expect?: boolean): R;
164
+ static tap<T extends Model, R extends readonly unknown[] | []>(this: Model.Type<T>, compute: Model.TapCallback<T, Promise<R> | (() => R) | null>, expect?: boolean): R | null;
165
+ static tap<T extends Model, R extends readonly unknown[] | []>(this: Model.Type<T>, compute: Model.TapCallback<T, Promise<R> | R>, expect: true): Exclude<R, undefined>;
166
+ static tap<T extends Model, R>(this: Model.Type<T>, init: Model.TapCallback<T, () => R>): NoVoid<R>;
167
+ static tap<T extends Model, R>(this: Model.Type<T>, init: Model.TapCallback<T, (() => R) | null>): NoVoid<R> | null;
168
+ static tap<T extends Model, R>(this: Model.Type<T>, compute: Model.TapCallback<T, Promise<R> | R>, expect: true): Exclude<R, undefined>;
169
+ static tap<T extends Model, R>(this: Model.Type<T>, compute: Model.TapCallback<T, Promise<R>>, expect?: boolean): NoVoid<R> | null;
170
+ static tap<T extends Model, R>(this: Model.Type<T>, compute: Model.TapCallback<T, R>, expect?: boolean): NoVoid<R>;
171
+ static tap<T extends Model>(this: Model.Type<T>, expect: true): NonOptionalValues<T>;
172
+ static tap<T extends Model>(this: Model.Type<T>, expect?: boolean): OptionalValues<T>;
173
+ protected static meta<T extends Class>(this: T): T;
174
+ protected static meta<T extends Class>(this: T, expect: true): NonOptionalValues<T>;
175
+ protected static meta<T extends Class>(this: T, expect?: boolean): OptionalValues<T>;
176
+ protected static meta<T, M extends Class>(this: M, from: (this: M, state: M) => Promise<T>, expect: true): Exclude<T, undefined>;
177
+ protected static meta<T, M extends Class>(this: M, from: (this: M, state: M) => Promise<T>, expect?: boolean): T;
178
+ protected static meta<T, M extends Class>(this: M, from: (this: M, state: M) => T, expect: true): Exclude<T, undefined>;
179
+ protected static meta<T, M extends Class>(this: M, from: (this: M, state: M) => T, expect?: boolean): T;
171
180
  /**
172
181
  * Static equivalent of `x instanceof this`.
173
182
  *
@@ -176,6 +185,54 @@ declare class Model {
176
185
  static isTypeof<T extends Model.Type>(this: T, maybe: any): maybe is T;
177
186
  }
178
187
 
188
+ type Listener = {
189
+ commit(): void;
190
+ release(): void;
191
+ };
192
+ declare namespace Subscriber {
193
+ type OnEvent<T = any> = (key: Model.Event<T> | null, source: Control) => Callback | void;
194
+ type Getter<T extends Model> = (within?: Subscriber<T> | undefined) => any;
195
+ }
196
+ declare class Subscriber<T extends Model = any> {
197
+ onUpdate: Subscriber.OnEvent;
198
+ proxy: T;
199
+ clear: () => void;
200
+ latest?: Model.Event<T>[];
201
+ active: boolean;
202
+ dependant: Set<Listener>;
203
+ watch: Map<any, boolean | (() => boolean | void)>;
204
+ parent: Control<T>;
205
+ constructor(parent: Control<T> | T, onUpdate: Subscriber.OnEvent);
206
+ get using(): Model.Key<T>[];
207
+ get(key: string, using?: Subscriber.Getter<T>): any;
208
+ follow(key: any, value?: boolean | (() => boolean | void)): void;
209
+ commit(): void;
210
+ release(): void;
211
+ private notify;
212
+ }
213
+
214
+ /**
215
+ * Property initializer, will run upon instance creation.
216
+ * Optional returned callback will run when once upon first access.
217
+ */
218
+ type Instruction<T> = (this: Control, key: string, thisArg: Control) => Instruction.Getter<T> | Instruction.Descriptor<T> | void;
219
+ declare namespace Instruction {
220
+ type Getter<T> = (within?: Subscriber) => T;
221
+ type Setter<T> = (value: T) => boolean | void;
222
+ type Runner = (on: Control, key: string) => Instruction.Descriptor<any> | undefined;
223
+ interface Descriptor<T> {
224
+ enumerable?: boolean;
225
+ value?: T;
226
+ get?: Getter<T>;
227
+ set?: Setter<T> | false;
228
+ }
229
+ }
230
+ /**
231
+ * Run instruction as controller sets itself up.
232
+ * This will specialize the behavior of a given property.
233
+ */
234
+ declare function add<T = any>(instruction: Instruction<any>, label?: string): T;
235
+
179
236
  declare namespace Control {
180
237
  /**
181
238
  * Called immediately when any key is changed or emitted.
@@ -195,6 +252,8 @@ declare class Control<T extends {} = any> {
195
252
  latest?: Model.Event<T>[];
196
253
  constructor(subject: T);
197
254
  watch(key: keyof T & string): void;
255
+ /** Throw suspense which resolves when key is set. */
256
+ waitFor(key: string): never;
198
257
  addListener(listener: Control.OnSync<T>): () => void;
199
258
  ref<K extends Model.Key<T>>(key: K, handler?: (this: T, value: T[K]) => boolean | void): (value: any) => void;
200
259
  update(key: Model.Key<T>): void;
@@ -213,27 +272,7 @@ declare namespace control {
213
272
  declare function control<T extends Model>(subject: T): Control<T>;
214
273
  declare function control<T extends Model>(subject: T, cb: control.OnReady<T>): Callback;
215
274
 
216
- /**
217
- * Property initializer, will run upon instance creation.
218
- * Optional returned callback will run when once upon first access.
219
- */
220
- type Instruction<T> = (this: Control, key: string, thisArg: Control) => Instruction.Getter<T> | Instruction.Descriptor<T> | void;
221
- declare namespace Instruction {
222
- type Getter<T> = (within?: Subscriber) => T;
223
- type Setter<T> = (value: T) => boolean | void;
224
- type Runner = (on: Control, key: string) => Instruction.Descriptor<any> | undefined;
225
- interface Descriptor<T> {
226
- enumerable?: boolean;
227
- value?: T;
228
- get?: Getter<T>;
229
- set?: Setter<T> | false;
230
- }
231
- }
232
- /**
233
- * Run instruction as controller sets itself up.
234
- * This will specialize the behavior of a given property.
235
- */
236
- declare function add<T = any>(instruction: Instruction<any>, label?: string): T;
275
+ declare function getParent<T extends Model>(from: Model, type?: Model.Type<T>): T;
237
276
 
238
277
  type Async<T = any> = (...args: any[]) => Promise<T>;
239
278
  /**
@@ -256,6 +295,10 @@ declare function run<S>(action: Async<S>): typeof action & {
256
295
  declare namespace get {
257
296
  type Function<T, S = any> = (this: S, on: S) => T;
258
297
  type Factory<R, T> = (this: T, property: string, on: T) => Function<R, T>;
298
+ type FindFunction<T extends Model = Model> = (type: typeof Model, relativeTo: Model, required: boolean) => Source<T>;
299
+ type Source<T extends Model = Model> = (callback: (x: T) => void) => void;
300
+ /** Assign fetch algorithm for get instruction. */
301
+ let using: (fn: FindFunction) => typeof get;
259
302
  }
260
303
  /**
261
304
  * Fetches and assigns the controller which spawned this host.
@@ -422,142 +465,18 @@ declare function use<T extends {}>(from: () => T, callback?: (i: T) => void): T;
422
465
  */
423
466
  declare function use<T extends {}>(peer: T, callback?: (i: T) => void): T;
424
467
 
425
- declare namespace MVC {
426
- type EffectCallback<T = MVC> = (found: T) => Callback | void;
427
- type ForceUpdate = {
428
- /** Force an update in current component. */
429
- (): void;
430
- /**
431
- * Force an update and again after promise either resolves or rejects.
432
- * Will return a duplicate of given Promise, which resolves after refresh.
433
- */
434
- <T = void>(passthru?: Promise<T>): Promise<T>;
435
- /**
436
- * Force a update while calling async function.
437
- * A refresh will occur both before and after given function.
438
- * Any actions performed before first `await` will occur before refresh!
439
- */
440
- <T = void>(invoke?: () => Promise<T>): Promise<T>;
441
- };
442
- type TapCallback<T extends Model, R> = (this: T, model: T, update: MVC.ForceUpdate) => R;
468
+ declare class Register {
469
+ private table;
470
+ register: Map<string | number, Model | Model.Type>;
471
+ private has;
472
+ get<T extends Model>(Type: Model.Type<T>): T | undefined;
473
+ add(input: Model.New | Model, key?: number | string): Model;
474
+ push(): this;
475
+ pop(): void;
443
476
  }
444
- declare class MVC extends Model {
445
- end(force?: boolean): boolean | void;
446
- static global?: boolean;
447
- static keepAlive?: boolean;
448
- /**
449
- * Create a new instance of this model and activate its managed state.
450
- *
451
- * @param args - arguments sent to constructor
452
- */
453
- static new<T extends Class>(this: T, ...args: ConstructorParameters<T>): InstanceOf<T>;
454
- /**
455
- * **React Hook** - Fetch most instance of this controller from context, if it exists.
456
- *
457
- * @param required - Unless false, will throw where instance cannot be found.
458
- */
459
- static get<T extends MVC>(this: Model.Type<T>, required?: boolean, effectCallback?: MVC.EffectCallback<T>): T;
460
- /**
461
- * **React Hook** - Fetch most instance of this controller from context.
462
- *
463
- * @param required - If false, may return undefined.
464
- */
465
- static get<T extends MVC>(this: Model.Type<T>, required: false, effectCallback?: MVC.EffectCallback<T | undefined>): T | undefined;
466
- /**
467
- * **React Hook** - Fetch instance.
468
- *
469
- * Effect callback will run once if found, throw if not found.
470
- * Returned function is called on unmount.
471
- */
472
- static get<I extends MVC>(this: Model.Type<I>, effectCallback: MVC.EffectCallback<I>): I | undefined;
473
- /**
474
- * **React Hook** - Fetch and subscribe to instance of this controller within ambient component.
475
- */
476
- static tap<T extends MVC>(this: Model.Type<T>): T;
477
- static tap<T extends MVC, R extends readonly unknown[] | []>(this: Model.Type<T>, compute: MVC.TapCallback<T, R | (() => R)>, expect?: boolean): R;
478
- static tap<T extends MVC, R extends readonly unknown[] | []>(this: Model.Type<T>, compute: MVC.TapCallback<T, Promise<R> | (() => R) | null>, expect?: boolean): R | null;
479
- static tap<T extends MVC, R extends readonly unknown[] | []>(this: Model.Type<T>, compute: MVC.TapCallback<T, Promise<R> | R>, expect: true): Exclude<R, undefined>;
480
- static tap<T extends MVC, R>(this: Model.Type<T>, init: MVC.TapCallback<T, () => R>): NoVoid<R>;
481
- static tap<T extends MVC, R>(this: Model.Type<T>, init: MVC.TapCallback<T, (() => R) | null>): NoVoid<R> | null;
482
- static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, Promise<R> | R>, expect: true): Exclude<R, undefined>;
483
- static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, Promise<R>>, expect?: boolean): NoVoid<R> | null;
484
- static tap<T extends MVC, R>(this: Model.Type<T>, compute: MVC.TapCallback<T, R>, expect?: boolean): NoVoid<R>;
485
- static tap<T extends MVC>(this: Model.Type<T>, expect: true): NonOptionalValues<T>;
486
- static tap<T extends MVC>(this: Model.Type<T>, expect?: boolean): OptionalValues<T>;
487
- static use<I extends MVC>(this: Model.Type<I>, watch: Model.Key<I>[], callback?: (instance: I) => void): I;
488
- static use<I extends MVC>(this: Model.Type<I>, callback?: (instance: I) => void): I;
489
- static use<I extends MVC>(this: Model.Type<I>, apply: Model.Compat<I>, keys?: Model.Event<I>[]): I;
490
- protected static meta<T extends Class>(this: T): T;
491
- protected static meta<T extends Class>(this: T, expect: true): NonOptionalValues<T>;
492
- protected static meta<T extends Class>(this: T, expect?: boolean): OptionalValues<T>;
493
- protected static meta<T, M extends Class>(this: M, from: (this: M, state: M) => Promise<T>, expect: true): Exclude<T, undefined>;
494
- protected static meta<T, M extends Class>(this: M, from: (this: M, state: M) => Promise<T>, expect?: boolean): T;
495
- protected static meta<T, M extends Class>(this: M, from: (this: M, state: M) => T, expect: true): Exclude<T, undefined>;
496
- protected static meta<T, M extends Class>(this: M, from: (this: M, state: M) => T, expect?: boolean): T;
497
- }
498
-
499
- declare namespace Consumer {
500
- type HasProps<E extends Class> = {
501
- /** @deprecated - use for instead */
502
- of?: never;
503
- /** Type of controller to fetch from context. */
504
- for: E;
505
- /**
506
- * Getter function. Is called on every natural render of this component.
507
- * Will throw if usable instance cannot be found in context.
508
- */
509
- has: (value: InstanceType<E>) => void;
510
- };
511
- type GetProps<E extends Class> = {
512
- /** @deprecated - use for instead */
513
- of?: never;
514
- /** Type of controller to fetch from context. */
515
- for: E;
516
- /** Getter function. Is called on every natural render of this component. */
517
- get: (value: InstanceType<E> | undefined) => void;
518
- };
519
- type RenderProps<E extends Class> = {
520
- /** @deprecated - use for instead */
521
- of?: never;
522
- /** Type of controller to fetch from context. */
523
- for: E;
524
- /**
525
- * Render function, will receive instance of desired controller.
526
- *
527
- * Similar to `tap()`, updates to properties accessed in
528
- * this function will cause a refresh when they change.
529
- */
530
- children: (value: InstanceType<E>) => React.ReactElement<any, any> | null;
531
- };
532
- type Props<T extends Class> = HasProps<T> | GetProps<T> | RenderProps<T>;
533
- }
534
- declare function Consumer<T extends Class>(props: Consumer.Props<T>): any;
535
-
536
- declare namespace Provider {
537
- type Item = Model | Model.New;
538
- type Multiple<T extends Item = Item> = T[] | {
539
- [key: string]: T;
540
- };
541
- type Instance<E> = E extends Class ? InstanceType<E> : E extends Model ? E : never;
542
- type NormalProps<E, I = Instance<E>> = {
543
- for: E;
544
- fallback?: React.ReactNode;
545
- children?: React.ReactNode | ((instance: I) => React.ReactNode);
546
- use?: Model.Compat<I>;
547
- };
548
- type MultipleProps<T extends Item> = {
549
- for: Multiple<T>;
550
- fallback?: React.ReactNode;
551
- children?: React.ReactNode;
552
- use?: Model.Compat<Instance<T>>;
553
- };
554
- type Props<T extends Item> = MultipleProps<T> | NormalProps<T>;
555
- }
556
- declare function Provider<T extends Provider.Item>(props: Provider.Props<T>): JSX.Element;
557
477
 
558
- declare class Global extends MVC {
559
- static global: boolean;
560
- static keepAlive: boolean;
561
- }
478
+ declare const Internal: {
479
+ getParent: typeof getParent;
480
+ };
562
481
 
563
- export { Consumer, Debug, Global, MVC, MVC as Model, Provider, add, MVC as default, get, ref, run, set, use };
482
+ export { Control, Debug, Internal, Model, Register, Subscriber, add, Model as default, get, ref, run, set, use };