@expressive/mvc 1.0.0-beta.19 → 1.0.0-beta.22
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.js +587 -515
- package/package.json +11 -6
- package/types/index.d.ts +0 -1
- package/types/instructions.d.ts +54 -14
- package/types/model.d.ts +56 -57
- package/types/types.d.ts +4 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expressive/mvc",
|
|
3
|
-
"version": "1.0.0-beta.19",
|
|
4
3
|
"description": "Use classes to define state in React!",
|
|
4
|
+
"version": "1.0.0-beta.22",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Gabe Klein",
|
|
7
7
|
"email": "gabe@termtm.com",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"react",
|
|
17
|
-
"
|
|
17
|
+
"mvc"
|
|
18
18
|
],
|
|
19
19
|
"main": "lib/index.js",
|
|
20
20
|
"types": "types/index.d.ts",
|
|
@@ -24,10 +24,9 @@
|
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "rollup --config",
|
|
27
|
-
"watch": "
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"coverage": "jest --collectCoverage"
|
|
27
|
+
"watch": "jest --watchAll",
|
|
28
|
+
"test": "jest --collectCoverage",
|
|
29
|
+
"prebuild": "rm -rf lib/"
|
|
31
30
|
},
|
|
32
31
|
"peerDependencies": {
|
|
33
32
|
"react": ">=17.0.2"
|
|
@@ -44,8 +43,14 @@
|
|
|
44
43
|
"react-test-renderer": "^17.0.2",
|
|
45
44
|
"rollup": "^2.52.2",
|
|
46
45
|
"rollup-plugin-typescript2": "^0.30.0",
|
|
46
|
+
"semantic-release": "^18.0.1",
|
|
47
47
|
"ts-jest": "^27.0.3",
|
|
48
48
|
"tslib": "^2.3.0",
|
|
49
49
|
"typescript": "typescript@>=3.8 <5.0"
|
|
50
|
+
},
|
|
51
|
+
"release": {
|
|
52
|
+
"branches": [
|
|
53
|
+
{ "name": "beta", "prerelease": true }
|
|
54
|
+
]
|
|
50
55
|
}
|
|
51
56
|
}
|
package/types/index.d.ts
CHANGED
package/types/instructions.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import Model
|
|
1
|
+
import Model from '.';
|
|
2
2
|
import { Async, Class, InstanceOf, InterceptCallback } from './types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Run instruction as controller sets itself up.
|
|
6
6
|
* This will specialize the behavior of a given property.
|
|
7
7
|
**/
|
|
8
|
-
export function
|
|
8
|
+
export function apply <T = any> (instruction: Model.Instruction<T>, name?: string): T;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Creates a new child-instance of specified controller.
|
|
@@ -116,15 +116,28 @@ export function tap <T extends Class> (Type: T, required?: boolean): InstanceOf<
|
|
|
116
116
|
export function on <T = any> (initialValue: undefined, onUpdate: InterceptCallback<T>): T | undefined;
|
|
117
117
|
export function on <T = any> (initialValue: T, onUpdate: InterceptCallback<T>): T;
|
|
118
118
|
|
|
119
|
+
/** Object with references to all managed values of `T`. */
|
|
120
|
+
export type Refs <T extends Model> = { [P in Model.Fields<T>]: Model.Ref<T[P]> };
|
|
121
|
+
|
|
119
122
|
/**
|
|
120
|
-
* Creates
|
|
123
|
+
* Creates an object with references to all managed values.
|
|
124
|
+
* Each property will set value in state when invoked.
|
|
125
|
+
*
|
|
126
|
+
* *Properties are simultaneously a ref-function and ref-object, use as needed.*
|
|
127
|
+
*
|
|
128
|
+
* @param target - Source model from which to reference values.
|
|
129
|
+
*/
|
|
130
|
+
export function ref <T extends Model> (target: T): Refs<T>;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Creates a ref-compatible property.
|
|
121
134
|
* Will persist value, and updates to this are made part of controller event-stream.
|
|
122
135
|
*
|
|
123
136
|
* *Output is simultaneously a ref-function and ref-object, use as needed.*
|
|
124
137
|
*
|
|
125
138
|
* @param callback - Optional callback to synchronously fire when reference is first set or does update.
|
|
126
139
|
*/
|
|
127
|
-
export function ref <T = HTMLElement> (
|
|
140
|
+
export function ref <T = HTMLElement> (callback?: InterceptCallback<T>): Model.Ref<T>;
|
|
128
141
|
|
|
129
142
|
/**
|
|
130
143
|
* Sets an exotic method with managed ready-state. Property accepts an async function.
|
|
@@ -141,29 +154,29 @@ export function act <T extends Async> (action: T): T & { active: boolean };
|
|
|
141
154
|
/**
|
|
142
155
|
* Implement a computed value; output is returned by function from provided factory.
|
|
143
156
|
*
|
|
144
|
-
* @param
|
|
157
|
+
* @param compute - Factory function to generate a getter to subscribe dependancies.
|
|
145
158
|
*/
|
|
146
|
-
export function from <R> (
|
|
159
|
+
export function from <R> (compute: (property: string) => (this: any, state: any) => R): R;
|
|
147
160
|
|
|
148
161
|
/**
|
|
149
162
|
* Implement a computed value; output will be generated by provided function.
|
|
150
163
|
*
|
|
151
164
|
* @param source - Source Model to find and subscribe to, for input.
|
|
152
165
|
*
|
|
153
|
-
* @param
|
|
154
|
-
* Will update automatically as
|
|
166
|
+
* @param compute - Compute function. Bound to a subscriber-proxy of source, returns output value.
|
|
167
|
+
* Will update automatically as input values change.
|
|
155
168
|
*/
|
|
156
|
-
export function from <T extends Class, R> (source: T,
|
|
169
|
+
export function from <T extends Class, R> (source: T, compute: (this: InstanceOf<T>, on: InstanceOf<T>) => R): R;
|
|
157
170
|
|
|
158
171
|
/**
|
|
159
172
|
* Implement a computed value; output will be generated by provided function.
|
|
160
173
|
*
|
|
161
|
-
* @param source - Source model from which computed value will be
|
|
174
|
+
* @param source - Source model from which computed value will be a subscriber.
|
|
162
175
|
*
|
|
163
|
-
* @param
|
|
164
|
-
* Will update automatically as
|
|
176
|
+
* @param compute - Compute function. Bound to a subscriber-proxy of source, returns output value.
|
|
177
|
+
* Will update automatically as input values change.
|
|
165
178
|
*/
|
|
166
|
-
export function from <T, R> (source: T,
|
|
179
|
+
export function from <T, R> (source: T, compute: (this: T, on: T) => R): R;
|
|
167
180
|
|
|
168
181
|
/**
|
|
169
182
|
* Memoized value. Computes and stores a value returned by provided factory.
|
|
@@ -179,4 +192,31 @@ export function memo <T> (compute: () => T, lazy?: boolean): T;
|
|
|
179
192
|
*
|
|
180
193
|
* @param value - starting value of property.
|
|
181
194
|
*/
|
|
182
|
-
export function lazy <T> (value?: T): T;
|
|
195
|
+
export function lazy <T> (value?: T): T;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Suspend during the execution of given function to obtain value.
|
|
199
|
+
*
|
|
200
|
+
* @param waitFor - Async function to suspend for.
|
|
201
|
+
*/
|
|
202
|
+
export function pending (waitFor: () => Promise<void>): undefined;
|
|
203
|
+
export function pending <T> (waitFor: () => Promise<T>): T;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Suspend for a computed value, returned by syncronous function.
|
|
207
|
+
*
|
|
208
|
+
* If accessed while computing to undefined, will throw a promise. Function is subscribed
|
|
209
|
+
* and will re-evaluate anytime used properties change. Once function returns any value,
|
|
210
|
+
* outstanding promises resolve and are not thrown on subsequent access of this property.
|
|
211
|
+
*
|
|
212
|
+
* Similar to `from`, compute function will only run when inputs change and not upon access.
|
|
213
|
+
*
|
|
214
|
+
* This behavior is recursive. If return value _becomes_ undefined, property
|
|
215
|
+
* access will throw Promises again, awaiting its next value.
|
|
216
|
+
*
|
|
217
|
+
* @param source - Source object, from which computed value will be a subscriber.
|
|
218
|
+
*
|
|
219
|
+
* @param compute - Compute function returns output value. Bound to a subscriber of source.
|
|
220
|
+
* Will re-run automatically as input values change.
|
|
221
|
+
*/
|
|
222
|
+
export function pending <T, R> (source: T, compute: (this: T, on: T) => R): Exclude<R, undefined>;
|
package/types/model.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { Key } from 'react';
|
|
2
|
+
|
|
1
3
|
import Lifecycle from './lifecycle';
|
|
2
4
|
import { Select, Selector } from './selector';
|
|
3
|
-
import { Class, InstanceOf,
|
|
5
|
+
import { BunchOf, Callback, Class, InstanceOf, Query, RequestCallback, UpdateCallback } from './types';
|
|
4
6
|
|
|
5
7
|
interface PropertyDescriptor<T> {
|
|
6
8
|
configurable?: boolean;
|
|
@@ -151,7 +153,8 @@ declare const CONTROL: unique symbol;
|
|
|
151
153
|
declare const LOCAL: unique symbol;
|
|
152
154
|
declare const STATE: unique symbol;
|
|
153
155
|
|
|
154
|
-
export
|
|
156
|
+
export interface Model extends Lifecycle {}
|
|
157
|
+
export abstract class Model {
|
|
155
158
|
/** Controller for this instance. */
|
|
156
159
|
[CONTROL]: Model.Controller;
|
|
157
160
|
|
|
@@ -278,6 +281,50 @@ export abstract class State {
|
|
|
278
281
|
|
|
279
282
|
tap <K extends Model.SelectField<this>> (key: K, expect?: boolean): ReturnType<K>;
|
|
280
283
|
tap <K extends Model.SelectField<this>> (key: K, expect: true): Exclude<ReturnType<K>, undefined>;
|
|
284
|
+
|
|
285
|
+
// Keyed
|
|
286
|
+
on <S extends Model.SelectEvents<this>> (via: S, cb: Selector.Callback<S, this>, squash?: false, once?: boolean): Callback;
|
|
287
|
+
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
|
|
288
|
+
// Squash
|
|
289
|
+
on <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true, once?: boolean): Callback;
|
|
290
|
+
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true, once?: boolean): Callback;
|
|
291
|
+
// Unknown
|
|
292
|
+
on <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean, once?: boolean): Callback;
|
|
293
|
+
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean, once?: boolean): Callback;
|
|
294
|
+
|
|
295
|
+
// Keyed
|
|
296
|
+
once <S extends Model.SelectEvents<this>> (via: S, cb: Selector.Callback<S, this>, squash?: false): Callback;
|
|
297
|
+
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false): Callback;
|
|
298
|
+
// Squash
|
|
299
|
+
once <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true): Callback;
|
|
300
|
+
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true): Callback;
|
|
301
|
+
// Promise
|
|
302
|
+
once <S extends Model.SelectEvents<this>> (via: S): Promise<Selector.From<S>[]>;
|
|
303
|
+
once <P extends Model.EventsCompat<this>> (key: P | P[]): Promise<P[]>;
|
|
304
|
+
// Unknown
|
|
305
|
+
once <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean): Callback;
|
|
306
|
+
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean): Callback;
|
|
307
|
+
|
|
308
|
+
effect(callback: (this: this, state: this) => void, select?: Model.SelectFields<this>): Callback;
|
|
309
|
+
effect(callback: (this: this, state: this) => void, select?: (keyof this)[]): Callback;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
313
|
+
*
|
|
314
|
+
* This method will fire lifecycle events on given controller.
|
|
315
|
+
*
|
|
316
|
+
* @param id - Argument passed to controller-lifecycle methods. Use to identify the consumer.
|
|
317
|
+
*/
|
|
318
|
+
tag(id?: any): this;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
322
|
+
*
|
|
323
|
+
* This method will fire lifecycle events on given controller.
|
|
324
|
+
*
|
|
325
|
+
* @param idFactory - Will be invoked with fetched instance. Use this to register a tag as-needed.
|
|
326
|
+
*/
|
|
327
|
+
tag(idFactory: (idFactory: this) => any): this;
|
|
281
328
|
|
|
282
329
|
/** Use symbol to access controller of a model. */
|
|
283
330
|
static CONTROL: typeof CONTROL;
|
|
@@ -385,61 +432,6 @@ export abstract class State {
|
|
|
385
432
|
static tap <T extends Class, I extends InstanceOf<T>, K extends Model.Fields<I>> (this: T, key: K, expect: true): Exclude<I[K], undefined>;
|
|
386
433
|
static tap <T extends Class, I extends InstanceOf<T>, K extends Model.SelectField<I>> (this: T, key: K, expect: true): Exclude<ReturnType<K>, undefined>;
|
|
387
434
|
|
|
388
|
-
/**
|
|
389
|
-
* Static equivalent of `x instanceof this`.
|
|
390
|
-
*
|
|
391
|
-
* Will determine if provided class is a subtype of this one.
|
|
392
|
-
*/
|
|
393
|
-
static isTypeof <T extends Class>(this: T, subject: any): subject is T;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
export interface Model extends Lifecycle {}
|
|
397
|
-
export abstract class Model extends State {
|
|
398
|
-
// Keyed
|
|
399
|
-
on <S extends Model.SelectEvents<this>> (via: S, cb: Selector.Callback<S, this>, squash?: false, once?: boolean): Callback;
|
|
400
|
-
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false, once?: boolean): Callback;
|
|
401
|
-
// Squash
|
|
402
|
-
on <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true, once?: boolean): Callback;
|
|
403
|
-
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true, once?: boolean): Callback;
|
|
404
|
-
// Unknown
|
|
405
|
-
on <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean, once?: boolean): Callback;
|
|
406
|
-
on <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean, once?: boolean): Callback;
|
|
407
|
-
|
|
408
|
-
// Keyed
|
|
409
|
-
once <S extends Model.SelectEvents<this>> (via: S, cb: Selector.Callback<S, this>, squash?: false): Callback;
|
|
410
|
-
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: UpdateCallback<this, P>, squash?: false): Callback;
|
|
411
|
-
// Squash
|
|
412
|
-
once <S extends Model.SelectEvents<this>> (via: S, cb: (keys: Selector.From<S>[]) => void, squash: true): Callback;
|
|
413
|
-
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: (keys: P[]) => void, squash: true): Callback;
|
|
414
|
-
// Promise
|
|
415
|
-
once <S extends Model.SelectEvents<this>> (via: S): Promise<Selector.From<S>[]>;
|
|
416
|
-
once <P extends Model.EventsCompat<this>> (key: P | P[]): Promise<P[]>;
|
|
417
|
-
// Unknown
|
|
418
|
-
once <S extends Model.SelectEvents<this>> (via: S, cb: unknown, squash: boolean): Callback;
|
|
419
|
-
once <P extends Model.EventsCompat<this>> (key: P | P[], listener: unknown, squash: boolean): Callback;
|
|
420
|
-
|
|
421
|
-
effect(callback: (this: this, state: this) => void, select?: Model.SelectFields<this>): Callback;
|
|
422
|
-
effect(callback: (this: this, state: this) => void, select?: (keyof this)[]): Callback;
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
426
|
-
*
|
|
427
|
-
* This method will fire lifecycle events on given controller.
|
|
428
|
-
*
|
|
429
|
-
* @param id - Argument passed to controller-lifecycle methods. Use to identify the consumer.
|
|
430
|
-
*/
|
|
431
|
-
tag(id?: Key): this;
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
435
|
-
*
|
|
436
|
-
* This method will fire lifecycle events on given controller.
|
|
437
|
-
*
|
|
438
|
-
* @param idFactory - Will be invoked with fetched instance. Use this to register a tag as-needed.
|
|
439
|
-
*/
|
|
440
|
-
tag(idFactory: (idFactory: this) => Key | void): this;
|
|
441
|
-
|
|
442
|
-
|
|
443
435
|
/**
|
|
444
436
|
* **React Hook** - Attach to instance of this controller within ambient component.
|
|
445
437
|
*
|
|
@@ -473,6 +465,13 @@ export abstract class Model extends State {
|
|
|
473
465
|
* Documentation TBD.
|
|
474
466
|
*/
|
|
475
467
|
static meta <T extends Class, K extends Model.SelectField<T>> (this: T, key?: K): ReturnType<K>;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Static equivalent of `x instanceof this`.
|
|
471
|
+
*
|
|
472
|
+
* Will determine if provided class is a subtype of this one.
|
|
473
|
+
*/
|
|
474
|
+
static isTypeof <T extends Class>(this: T, subject: any): subject is T;
|
|
476
475
|
}
|
|
477
476
|
|
|
478
477
|
export class Singleton extends Model {
|
package/types/types.d.ts
CHANGED
|
@@ -12,4 +12,7 @@ export type EffectCallback<T, A = T> = (this: T, argument: A) => Callback | Prom
|
|
|
12
12
|
export type UpdateCallback<T, P> = (this: T, value: IfApplicable<T, P>, changed: P) => void;
|
|
13
13
|
export type InterceptCallback<T> = (argument: T) => ((next: T) => void) | Promise<any> | void | boolean;
|
|
14
14
|
|
|
15
|
-
export type RefFunction = (e: HTMLElement | null) => void;
|
|
15
|
+
export type RefFunction = (e: HTMLElement | null) => void;
|
|
16
|
+
|
|
17
|
+
export type Recursive<T> = { [K in keyof T]: Recursive<Omit<T, K>> };
|
|
18
|
+
export type Query = (select: Recursive<{}>) => void;
|