@cleanweb/react 1.1.1-beta.20 → 1.1.1-beta.23
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/build/base/merged-state.js +2 -2
- package/build/base/methods.d.ts +16 -0
- package/build/base/methods.js +2 -2
- package/build/classy/class.d.ts +42 -8
- package/build/classy/class.js +21 -6
- package/build/classy/instance.d.ts +31 -7
- package/build/classy/instance.js +6 -5
- package/build/classy/logic/hook-types.d.ts +18 -0
- package/build/classy/logic/hook-types.js +2 -0
- package/build/classy/logic/index.d.ts +77 -0
- package/build/classy/logic/index.js +120 -0
- package/build/classy/logic/instance-types.d.ts +19 -0
- package/build/classy/logic/instance-types.js +2 -0
- package/build/classy/logic/static-types.d.ts +17 -0
- package/build/classy/logic/static-types.js +2 -0
- package/build/globals.d.ts +12 -0
- package/build/tsconfig.json +1 -0
- package/package.json +1 -1
- package/build/classy/logic.d.ts +0 -57
- package/build/classy/logic.js +0 -81
@@ -71,9 +71,9 @@ var MergedState = /** @class */ (function () {
|
|
71
71
|
return MergedState;
|
72
72
|
}());
|
73
73
|
var useMergedState = function (initialState) {
|
74
|
-
var cleanState = (0, react_1.useMemo)(function () {
|
74
|
+
var cleanState = (0, react_1.useRef)((0, react_1.useMemo)(function () {
|
75
75
|
return new MergedState(initialState);
|
76
|
-
}, []);
|
76
|
+
}, [])).current;
|
77
77
|
MergedState.useRefresh.call(cleanState);
|
78
78
|
return cleanState;
|
79
79
|
};
|
package/build/base/methods.d.ts
CHANGED
@@ -23,3 +23,19 @@ type UseMethods = {
|
|
23
23
|
*/
|
24
24
|
declare const useMethods: UseMethods;
|
25
25
|
export { useMethods };
|
26
|
+
/** /testing: {
|
27
|
+
let a = async () => {
|
28
|
+
const a: object = {b: ''};
|
29
|
+
|
30
|
+
type t = keyof typeof a;
|
31
|
+
|
32
|
+
class MyMethods extends ComponentMethods<WeakEmptyObject, null> {
|
33
|
+
// static getInitialState = () => ({});
|
34
|
+
};
|
35
|
+
|
36
|
+
const { useCleanState } = (await import('./state.js'));
|
37
|
+
|
38
|
+
const self = useMethods(MyMethods, {});
|
39
|
+
self.state;
|
40
|
+
}
|
41
|
+
}/**/
|
package/build/base/methods.js
CHANGED
@@ -46,7 +46,7 @@ var useMethods = function () {
|
|
46
46
|
return methods;
|
47
47
|
};
|
48
48
|
exports.useMethods = useMethods;
|
49
|
-
|
49
|
+
/** /testing: {
|
50
50
|
let a = async () => {
|
51
51
|
const a: object = {b: ''};
|
52
52
|
|
@@ -61,4 +61,4 @@ exports.useMethods = useMethods;
|
|
61
61
|
const self = useMethods(MyMethods, {});
|
62
62
|
self.state;
|
63
63
|
}
|
64
|
-
}
|
64
|
+
}/**/
|
package/build/classy/class.d.ts
CHANGED
@@ -4,12 +4,15 @@ import type { IComponentInstanceClass } from './instance';
|
|
4
4
|
import { ComponentInstance } from './instance';
|
5
5
|
import { THooksBase } from './logic';
|
6
6
|
export declare const useRerender: () => () => void;
|
7
|
-
type ComponentClassParams = ConstructorParameters<typeof ClassComponent>;
|
8
7
|
type o = object;
|
9
|
-
|
8
|
+
type ComponentClassOwnStaticKeys = Exclude<keyof typeof ClassComponent, keyof IComponentInstanceClass>;
|
9
|
+
type ComponentClassOwnStatics = {
|
10
|
+
[Key in ComponentClassOwnStaticKeys]: (typeof ClassComponent)[Key];
|
11
|
+
};
|
12
|
+
export interface IComponentClass<Instance extends ClassComponent<o, o, THooksBase> = ClassComponent> extends Constructor<Instance>, ComponentClassOwnStatics, IComponentInstanceClass<Instance> {
|
10
13
|
}
|
11
|
-
type
|
12
|
-
type
|
14
|
+
type BaseClassComponent = ClassComponent<o, o, THooksBase>;
|
15
|
+
type Extractor = <TComponent extends IComponentClass<BaseClassComponent>>(this: NonNullable<typeof _Component>, _Component?: TComponent) => VoidFunctionComponent<InstanceType<TComponent>['props']>;
|
13
16
|
/**
|
14
17
|
* A superset of {@link ComponentInstance} that allows defining your
|
15
18
|
* component's JSX template directly inside the class.
|
@@ -63,7 +66,7 @@ export declare class ClassComponent<TProps extends o = WeakEmptyObject, TState e
|
|
63
66
|
* }
|
64
67
|
* ```
|
65
68
|
*/
|
66
|
-
template?: () =>
|
69
|
+
template?: () => (React.JSX.Element | null);
|
67
70
|
/**
|
68
71
|
* Manually trigger a rerender of your component.
|
69
72
|
* You should rarely ever need this. But if you are migrating
|
@@ -77,16 +80,31 @@ export declare class ClassComponent<TProps extends o = WeakEmptyObject, TState e
|
|
77
80
|
* Function Component Extractor *
|
78
81
|
**************************************/
|
79
82
|
/**
|
80
|
-
* Extract a
|
81
|
-
* your ClassComponent just like any other component.
|
83
|
+
* Extract a Function Component (FC) which can be used to render
|
84
|
+
* your ClassComponent just like any other React component.
|
82
85
|
*
|
83
|
-
* Each JSX reference to
|
86
|
+
* Each JSX reference to the returned component will render with
|
84
87
|
* a separate instance of your class.
|
85
88
|
*
|
86
89
|
* So you only need to call `YourClassComponent.FC()` once, then use the returned
|
87
90
|
* function component as many times as you need.
|
91
|
+
*
|
92
|
+
* It is recommended to store this returned value as a static member of
|
93
|
+
* your ClassComponent. While this value may be given any name, the name
|
94
|
+
* RC (for "React Component") is the recommended convention.
|
95
|
+
*
|
96
|
+
* @example <caption>Calling FC in your ClassComponent</caption>
|
97
|
+
* class Button extends ClassComponent {
|
98
|
+
* static readonly RC = this.FC();
|
99
|
+
* // Because of the static keyword, `this` here refers to the class itself, same as calling `Button.FC()`.
|
100
|
+
* }
|
101
|
+
*
|
102
|
+
* // Render with `<Button.RC />`, or export RC to use the component in other files.
|
103
|
+
* export default Button.RC;
|
88
104
|
*/
|
89
105
|
static readonly FC: Extractor;
|
106
|
+
/** @see {@link ClassComponent.FC} */
|
107
|
+
static readonly extract: Extractor;
|
90
108
|
}
|
91
109
|
interface HookWrapperProps<THookFunction extends AnyFunction> {
|
92
110
|
/**
|
@@ -115,3 +133,19 @@ type ClassComponentHookWrapper = <Hook extends AnyFunction>(props: HookWrapperPr
|
|
115
133
|
*/
|
116
134
|
export declare const Use: ClassComponentHookWrapper;
|
117
135
|
export {};
|
136
|
+
/** /testing: {
|
137
|
+
const a: object = {b: ''};
|
138
|
+
|
139
|
+
type t = keyof typeof a;
|
140
|
+
|
141
|
+
class MyComponentLogic extends ClassComponent<{}, {a: ''}> {
|
142
|
+
static getInitialState = () => ({a: '' as const});
|
143
|
+
// a = () => this.hooks.a = '';
|
144
|
+
|
145
|
+
useHooks = () => {
|
146
|
+
this.state.a;
|
147
|
+
};
|
148
|
+
};
|
149
|
+
|
150
|
+
const Template = MyComponentLogic.FC();
|
151
|
+
}/**/
|
package/build/classy/class.js
CHANGED
@@ -56,24 +56,37 @@ var ClassComponent = /** @class */ (function (_super) {
|
|
56
56
|
function ClassComponent() {
|
57
57
|
return _super !== null && _super.apply(this, arguments) || this;
|
58
58
|
}
|
59
|
+
var _a;
|
60
|
+
_a = ClassComponent;
|
59
61
|
/*************************************
|
60
62
|
* Function Component Extractor *
|
61
63
|
**************************************/
|
62
|
-
// @todo Attempt using implicit `this` value to allow rendering <MyComponent.FC /> directly.
|
63
|
-
// const FC = (props) => { const self = useMemo(() => useInstance(this, props), {}); return self.template(); }
|
64
64
|
/**
|
65
|
-
* Extract a
|
66
|
-
* your ClassComponent just like any other component.
|
65
|
+
* Extract a Function Component (FC) which can be used to render
|
66
|
+
* your ClassComponent just like any other React component.
|
67
67
|
*
|
68
|
-
* Each JSX reference to
|
68
|
+
* Each JSX reference to the returned component will render with
|
69
69
|
* a separate instance of your class.
|
70
70
|
*
|
71
71
|
* So you only need to call `YourClassComponent.FC()` once, then use the returned
|
72
72
|
* function component as many times as you need.
|
73
|
+
*
|
74
|
+
* It is recommended to store this returned value as a static member of
|
75
|
+
* your ClassComponent. While this value may be given any name, the name
|
76
|
+
* RC (for "React Component") is the recommended convention.
|
77
|
+
*
|
78
|
+
* @example <caption>Calling FC in your ClassComponent</caption>
|
79
|
+
* class Button extends ClassComponent {
|
80
|
+
* static readonly RC = this.FC();
|
81
|
+
* // Because of the static keyword, `this` here refers to the class itself, same as calling `Button.FC()`.
|
82
|
+
* }
|
83
|
+
*
|
84
|
+
* // Render with `<Button.RC />`, or export RC to use the component in other files.
|
85
|
+
* export default Button.RC;
|
73
86
|
*/
|
74
87
|
ClassComponent.FC = function FC(_Component) {
|
75
88
|
var Component = _Component !== null && _Component !== void 0 ? _Component : this;
|
76
|
-
var isClassComponentType = Component.prototype instanceof
|
89
|
+
var isClassComponentType = Component.prototype instanceof _a;
|
77
90
|
if (!Component.getInitialState || !isClassComponentType)
|
78
91
|
throw new Error('Attempted to initialize ClassComponent with invalid Class type. Either pass a class that extends ClassComponent to FC (e.g `export FC(MyComponent);`), or ensure it is called as a method on a ClassComponent constructor type (e.g `export MyComponent.FC()`).');
|
79
92
|
/*************************************
|
@@ -139,6 +152,8 @@ var ClassComponent = /** @class */ (function (_super) {
|
|
139
152
|
setFunctionName(Wrapper, "$".concat(Component.name, "$"));
|
140
153
|
return Wrapper;
|
141
154
|
};
|
155
|
+
/** @see {@link ClassComponent.FC} */
|
156
|
+
ClassComponent.extract = _a.FC;
|
142
157
|
return ClassComponent;
|
143
158
|
}(instance_1.ComponentInstance));
|
144
159
|
exports.ClassComponent = ClassComponent;
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import type { TStateData } from '../base/state';
|
2
|
-
import type { THooksBase
|
1
|
+
import type { ExtractCleanStateData, TStateData } from '../base/state';
|
2
|
+
import type { THooksBase } from './logic';
|
3
3
|
import { ComponentLogic } from './logic';
|
4
4
|
type AsyncAllowedEffectCallback = () => Awaitable<IVoidFunction>;
|
5
5
|
/** An empty function. It returns (void) without performing any operations. */
|
@@ -9,7 +9,7 @@ export declare const noOp: () => void;
|
|
9
9
|
* This provides a declarative API for working with your React function component's lifecycle,
|
10
10
|
* a simpler alternative to the imperative approach with `useEffect` and/or `useMemo`.
|
11
11
|
*/
|
12
|
-
export declare class ComponentInstance<TProps extends o = {}, TState extends TStateData = WeakEmptyObject, THooks extends THooksBase = void> extends ComponentLogic<TProps, TState, THooks> {
|
12
|
+
export declare class ComponentInstance<TProps extends o = {}, TState extends TStateData = WeakEmptyObject, THooks extends THooksBase = void> extends ComponentLogic.Class<TProps, TState, THooks> {
|
13
13
|
/**
|
14
14
|
* Runs only _before_ first render, i.e before the component instance is mounted.
|
15
15
|
* Useful for logic that is involved in determining what to render.
|
@@ -55,12 +55,36 @@ export declare class ComponentInstance<TProps extends o = {}, TState extends TSt
|
|
55
55
|
cleanUp: IVoidFunction;
|
56
56
|
}
|
57
57
|
type o = object;
|
58
|
-
type
|
59
|
-
|
58
|
+
type ComponentInstanceOwnStaticKeys = Exclude<keyof typeof ComponentInstance, keyof ComponentLogic.ClassType>;
|
59
|
+
type ComponentInstanceOwnStatics = {
|
60
|
+
[Key in ComponentInstanceOwnStaticKeys]: (typeof ComponentInstance)[Key];
|
61
|
+
};
|
62
|
+
export interface IComponentInstance<Instance extends ComponentInstance<o, o, THooksBase>> extends ComponentLogic.Instance<Instance>, Omit<ComponentInstance<Instance['props'], ExtractCleanStateData<Instance['state']>, Instance['_thooks']>, 'useHooks'> {
|
63
|
+
}
|
64
|
+
export interface IComponentInstanceClass<Instance extends ComponentInstance<o, o, THooksBase> = ComponentInstance> extends Constructor<IComponentInstance<Instance>>, ComponentInstanceOwnStatics, ComponentLogic.ClassType<Instance> {
|
60
65
|
}
|
61
66
|
type UseInstance = {
|
62
|
-
<Class extends
|
63
|
-
<Class extends
|
67
|
+
<Class extends IComponentInstanceClass<ComponentInstance<o, o, THooksBase>>>(Methods: Class): InstanceType<Class>;
|
68
|
+
<Class extends IComponentInstanceClass<ComponentInstance<o, o, THooksBase>>>(Methods: Class, props: InstanceType<Class>['props']): InstanceType<Class>;
|
64
69
|
};
|
65
70
|
export declare const useInstance: UseInstance;
|
66
71
|
export {};
|
72
|
+
/** /testing: {
|
73
|
+
class A extends ComponentInstance<{}, {}, object> {
|
74
|
+
static getInitialState: (p?: object) => ({putan: ''});
|
75
|
+
// k = this.props.o
|
76
|
+
a = this.state['_initialValues_']
|
77
|
+
|
78
|
+
// useHooks: (() => void | HardEmptyObject) | undefined;
|
79
|
+
// hard empty has every key
|
80
|
+
// weak empty has no key
|
81
|
+
// weak empty is not assignable to hard empty
|
82
|
+
}
|
83
|
+
|
84
|
+
const a = useInstance(A, {o: ''});
|
85
|
+
a.a;
|
86
|
+
|
87
|
+
// a.props['o'];
|
88
|
+
type bbbb = A['state'];
|
89
|
+
type ttt = bbbb['put'];
|
90
|
+
}/**/
|
package/build/classy/instance.js
CHANGED
@@ -102,7 +102,7 @@ var ComponentInstance = /** @class */ (function (_super) {
|
|
102
102
|
return _this;
|
103
103
|
}
|
104
104
|
return ComponentInstance;
|
105
|
-
}(logic_1.ComponentLogic));
|
105
|
+
}(logic_1.ComponentLogic.Class));
|
106
106
|
exports.ComponentInstance = ComponentInstance;
|
107
107
|
;
|
108
108
|
;
|
@@ -156,21 +156,22 @@ var useInstance = function () {
|
|
156
156
|
return instance;
|
157
157
|
};
|
158
158
|
exports.useInstance = useInstance;
|
159
|
-
|
160
|
-
class A extends ComponentInstance {
|
159
|
+
/** /testing: {
|
160
|
+
class A extends ComponentInstance<{}, {}, object> {
|
161
161
|
static getInitialState: (p?: object) => ({putan: ''});
|
162
162
|
// k = this.props.o
|
163
163
|
a = this.state['_initialValues_']
|
164
164
|
|
165
|
+
// useHooks: (() => void | HardEmptyObject) | undefined;
|
165
166
|
// hard empty has every key
|
166
167
|
// weak empty has no key
|
167
168
|
// weak empty is not assignable to hard empty
|
168
169
|
}
|
169
170
|
|
170
|
-
const p = {k: ''}
|
171
171
|
const a = useInstance(A, {o: ''});
|
172
|
+
a.a;
|
172
173
|
|
173
174
|
// a.props['o'];
|
174
175
|
type bbbb = A['state'];
|
175
176
|
type ttt = bbbb['put'];
|
176
|
-
}
|
177
|
+
}/**/
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import type { ComponentLogic } from '.';
|
2
|
+
import type { CLBaseType, IComponentLogic } from './instance-types';
|
3
|
+
import type { IComponentLogicClass } from './static-types';
|
4
|
+
/*************************************
|
5
|
+
* # Hooks *
|
6
|
+
**************************************/
|
7
|
+
/** */
|
8
|
+
type ULClassParam = IComponentLogicClass<IComponentLogic<CLBaseType>>;
|
9
|
+
export type UseLogic = {
|
10
|
+
<Class extends ULClassParam>(Methods: Class): InstanceType<Class>;
|
11
|
+
<Class extends ULClassParam>(Methods: Class, props: InstanceType<Class>['props']): InstanceType<Class>;
|
12
|
+
};
|
13
|
+
export type ULParams = [
|
14
|
+
Class: ComponentLogic.ClassType<ComponentLogic.Instance<CLBaseType>>,
|
15
|
+
props?: object
|
16
|
+
];
|
17
|
+
export type ULReturn = CLBaseType;
|
18
|
+
export {};
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import type { TCleanState, TStateData } from '../../base/state';
|
2
|
+
import type { IComponentLogicClass } from './static-types';
|
3
|
+
import type { CLBaseType, IComponentLogic } from './instance-types';
|
4
|
+
import type { UseLogic } from './hook-types';
|
5
|
+
export type HardEmpty = HardEmptyObject;
|
6
|
+
export type WeakEmpty = WeakEmptyObject;
|
7
|
+
export type THooksBase = object | void;
|
8
|
+
/**
|
9
|
+
* Base class for a class that holds methods intended for use in a function component,
|
10
|
+
* as well as a static method for initializing state.
|
11
|
+
*
|
12
|
+
* These methods will have access to the components state and props via
|
13
|
+
* `this.state` and `this.props` respectively.
|
14
|
+
*
|
15
|
+
* The special {@link Class['useHooks'] | useHooks} method allows you to consume
|
16
|
+
* React hooks within this class.
|
17
|
+
*
|
18
|
+
* Call the {@link useLogic} hook inside your function component to instantiate the class.
|
19
|
+
*/
|
20
|
+
export declare class ComponentLogic<TProps extends object = {}, TState extends TStateData = WeakEmpty, THooks extends THooksBase = void> {
|
21
|
+
readonly state: TCleanState<TState>;
|
22
|
+
readonly props: TProps;
|
23
|
+
readonly hooks: THooks extends object ? THooks : WeakEmptyObject;
|
24
|
+
/**
|
25
|
+
* Called before each instance of your component is mounted.
|
26
|
+
* It receives the initial `props` object and should return
|
27
|
+
* an object with the initial values for your component's state.
|
28
|
+
*
|
29
|
+
* PS: `p?: object` wierdly causes TS error in v^5.5.4; object is not assignable to the component's TProps.
|
30
|
+
*/
|
31
|
+
static getInitialState: (p?: any) => object;
|
32
|
+
/** Do not use. Will be undefined at runtime. */
|
33
|
+
readonly _thooks: THooks;
|
34
|
+
/**
|
35
|
+
* Call React hooks and expose any values your component
|
36
|
+
* needs by return an object with said values. The returned
|
37
|
+
* object will be accessible as `this.hooks`;
|
38
|
+
*/
|
39
|
+
useHooks: () => void;
|
40
|
+
}
|
41
|
+
export declare const useLogic: UseLogic;
|
42
|
+
export declare namespace ComponentLogic {
|
43
|
+
class Class<TProps extends object = {}, TState extends TStateData = WeakEmpty, THooks extends THooksBase = void> extends ComponentLogic<TProps, TState, THooks> {
|
44
|
+
}
|
45
|
+
type Instance<Instance extends CLBaseType = Class> = IComponentLogic<Instance>;
|
46
|
+
type ClassType<Instance extends CLBaseType = Class> = IComponentLogicClass<Instance>;
|
47
|
+
}
|
48
|
+
/** /testing: {
|
49
|
+
const a: object = {b: ''};
|
50
|
+
|
51
|
+
type t = keyof typeof a;
|
52
|
+
|
53
|
+
class MyComponentLogic extends ComponentLogic.Class<{}, {b: number}, {a: string}> {
|
54
|
+
static getInitialState = () => ({b: 7});
|
55
|
+
// b = this.state.put[''] + this.props.b;
|
56
|
+
|
57
|
+
useHooks = () => ({a: 'undefined'});
|
58
|
+
};
|
59
|
+
|
60
|
+
type tt = keyof {};
|
61
|
+
|
62
|
+
MyComponentLogic.getInitialState
|
63
|
+
const self = useLogic(MyComponentLogic);
|
64
|
+
self.useHooks();
|
65
|
+
|
66
|
+
|
67
|
+
const A = class C extends ComponentLogic.Class {
|
68
|
+
// static getInitialState = () => ({a: 'l'});
|
69
|
+
// a = () => this.state.yyy = '';
|
70
|
+
}
|
71
|
+
|
72
|
+
A.getInitialState();
|
73
|
+
|
74
|
+
// const oa = {['a' as unknown as symbol]: 'boo'};
|
75
|
+
const oa = {['a']: 'boo'};
|
76
|
+
useLogic(A, oa);
|
77
|
+
}/**/
|
@@ -0,0 +1,120 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
3
|
+
var extendStatics = function (d, b) {
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
7
|
+
return extendStatics(d, b);
|
8
|
+
};
|
9
|
+
return function (d, b) {
|
10
|
+
if (typeof b !== "function" && b !== null)
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
12
|
+
extendStatics(d, b);
|
13
|
+
function __() { this.constructor = d; }
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
15
|
+
};
|
16
|
+
})();
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
18
|
+
exports.useLogic = exports.ComponentLogic = void 0;
|
19
|
+
var react_1 = require("react");
|
20
|
+
var state_1 = require("../../base/state");
|
21
|
+
/**
|
22
|
+
* Base class for a class that holds methods intended for use in a function component,
|
23
|
+
* as well as a static method for initializing state.
|
24
|
+
*
|
25
|
+
* These methods will have access to the components state and props via
|
26
|
+
* `this.state` and `this.props` respectively.
|
27
|
+
*
|
28
|
+
* The special {@link Class['useHooks'] | useHooks} method allows you to consume
|
29
|
+
* React hooks within this class.
|
30
|
+
*
|
31
|
+
* Call the {@link useLogic} hook inside your function component to instantiate the class.
|
32
|
+
*/
|
33
|
+
var ComponentLogic = /** @class */ (function () {
|
34
|
+
function ComponentLogic() {
|
35
|
+
/**
|
36
|
+
* Call React hooks and expose any values your component
|
37
|
+
* needs by return an object with said values. The returned
|
38
|
+
* object will be accessible as `this.hooks`;
|
39
|
+
*/
|
40
|
+
this.useHooks = function () { };
|
41
|
+
}
|
42
|
+
/**
|
43
|
+
* Called before each instance of your component is mounted.
|
44
|
+
* It receives the initial `props` object and should return
|
45
|
+
* an object with the initial values for your component's state.
|
46
|
+
*
|
47
|
+
* PS: `p?: object` wierdly causes TS error in v^5.5.4; object is not assignable to the component's TProps.
|
48
|
+
*/
|
49
|
+
ComponentLogic.getInitialState = function (p) { return ({}); };
|
50
|
+
return ComponentLogic;
|
51
|
+
}());
|
52
|
+
exports.ComponentLogic = ComponentLogic;
|
53
|
+
;
|
54
|
+
var useLogic = function () {
|
55
|
+
var _a;
|
56
|
+
var args = [];
|
57
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
58
|
+
args[_i] = arguments[_i];
|
59
|
+
}
|
60
|
+
var Logic = args[0], _b = args[1], props = _b === void 0 ? {} : _b;
|
61
|
+
var state = (0, state_1.useCleanState)(Logic.getInitialState, props);
|
62
|
+
var self = (0, react_1.useRef)((0, react_1.useMemo)(function () {
|
63
|
+
return new Logic();
|
64
|
+
}, [])).current;
|
65
|
+
/** A proxy variable to allow typechecking of the assignment to `self.props` despite the need for "readonly" error suppression. */
|
66
|
+
var _propsProxy_;
|
67
|
+
/** A proxy variable to allow typechecking of the assignment to `self.state` despite the need for "readonly" error suppression. */
|
68
|
+
var _stateProxy_;
|
69
|
+
/** A proxy variable to allow typechecking of the assignment to `self.hooks` despite the need for "readonly" error suppression. */
|
70
|
+
var _hooksProxy_;
|
71
|
+
// @ts-expect-error
|
72
|
+
self.props = (_propsProxy_ = props);
|
73
|
+
// @ts-expect-error
|
74
|
+
self.state = (_stateProxy_ = state);
|
75
|
+
// @ts-expect-error
|
76
|
+
self.hooks = (_hooksProxy_ = (_a = self.useHooks()) !== null && _a !== void 0 ? _a : {});
|
77
|
+
return self;
|
78
|
+
};
|
79
|
+
exports.useLogic = useLogic;
|
80
|
+
(function (ComponentLogic) {
|
81
|
+
var Class = /** @class */ (function (_super) {
|
82
|
+
__extends(Class, _super);
|
83
|
+
function Class() {
|
84
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
85
|
+
}
|
86
|
+
return Class;
|
87
|
+
}(ComponentLogic));
|
88
|
+
ComponentLogic.Class = Class;
|
89
|
+
;
|
90
|
+
})(ComponentLogic || (exports.ComponentLogic = ComponentLogic = {}));
|
91
|
+
/** /testing: {
|
92
|
+
const a: object = {b: ''};
|
93
|
+
|
94
|
+
type t = keyof typeof a;
|
95
|
+
|
96
|
+
class MyComponentLogic extends ComponentLogic.Class<{}, {b: number}, {a: string}> {
|
97
|
+
static getInitialState = () => ({b: 7});
|
98
|
+
// b = this.state.put[''] + this.props.b;
|
99
|
+
|
100
|
+
useHooks = () => ({a: 'undefined'});
|
101
|
+
};
|
102
|
+
|
103
|
+
type tt = keyof {};
|
104
|
+
|
105
|
+
MyComponentLogic.getInitialState
|
106
|
+
const self = useLogic(MyComponentLogic);
|
107
|
+
self.useHooks();
|
108
|
+
|
109
|
+
|
110
|
+
const A = class C extends ComponentLogic.Class {
|
111
|
+
// static getInitialState = () => ({a: 'l'});
|
112
|
+
// a = () => this.state.yyy = '';
|
113
|
+
}
|
114
|
+
|
115
|
+
A.getInitialState();
|
116
|
+
|
117
|
+
// const oa = {['a' as unknown as symbol]: 'boo'};
|
118
|
+
const oa = {['a']: 'boo'};
|
119
|
+
useLogic(A, oa);
|
120
|
+
}/**/
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import type { ExtractCleanStateData } from '../../base';
|
2
|
+
import type { ComponentLogic, THooksBase } from '.';
|
3
|
+
/*************************************
|
4
|
+
* # Utils *
|
5
|
+
**************************************/
|
6
|
+
/** */
|
7
|
+
export type CLBaseType = ComponentLogic<object, object, THooksBase>;
|
8
|
+
type CLFromSubType<SubType extends CLBaseType> = ComponentLogic<SubType['props'], ExtractCleanStateData<SubType['state']>, SubType['_thooks']>;
|
9
|
+
/*************************************
|
10
|
+
* # Instance Type *
|
11
|
+
**************************************/
|
12
|
+
/** */
|
13
|
+
interface InstanceOverrides<Instance extends CLBaseType = ComponentLogic> {
|
14
|
+
useHooks: Instance['_thooks'] extends void ? () => (void | HardEmptyObject) : () => Instance['_thooks'];
|
15
|
+
}
|
16
|
+
type BaseInstance<Instance extends CLBaseType = ComponentLogic> = Omit<CLFromSubType<Instance>, keyof InstanceOverrides>;
|
17
|
+
export interface IComponentLogic<Instance extends CLBaseType = ComponentLogic> extends BaseInstance<Instance>, InstanceOverrides<Instance> {
|
18
|
+
}
|
19
|
+
export {};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import type { ExtractCleanStateData } from '../../base';
|
2
|
+
import type { ComponentLogic, THooksBase } from '.';
|
3
|
+
import type { CLBaseType } from './instance-types';
|
4
|
+
/*************************************
|
5
|
+
* # Utils *
|
6
|
+
**************************************/
|
7
|
+
type o = object;
|
8
|
+
/*************************************
|
9
|
+
* # Class Static Side *
|
10
|
+
**************************************/
|
11
|
+
interface StaticOverrides<Instance extends CLBaseType = ComponentLogic> extends Constructor<Instance> {
|
12
|
+
getInitialState: (props?: Instance['props']) => ExtractCleanStateData<Instance['state']>;
|
13
|
+
}
|
14
|
+
type BaseStatics = Omit<typeof ComponentLogic, 'prototype' | keyof StaticOverrides>;
|
15
|
+
export interface IComponentLogicClass<Instance extends ComponentLogic<o, o, THooksBase> = ComponentLogic> extends BaseStatics, StaticOverrides<Instance> {
|
16
|
+
}
|
17
|
+
export {};
|
package/build/globals.d.ts
CHANGED
@@ -1,4 +1,16 @@
|
|
1
1
|
declare const UniqueSecretSymbolKey: unique symbol;
|
2
|
+
/** /testing: {
|
3
|
+
const mySymbol = Symbol('asdfgh') as symbol;
|
4
|
+
|
5
|
+
const tt = {
|
6
|
+
// [mySymbol]: '' as never,
|
7
|
+
// [UniqueSecretSymbolKey]: '',
|
8
|
+
// '': '',
|
9
|
+
}
|
10
|
+
|
11
|
+
let TT: WeakEmptyObject = {};
|
12
|
+
TT = tt;
|
13
|
+
}/**/
|
2
14
|
declare global {
|
3
15
|
type Optional<BaseType, AllowNull extends boolean = true> = (AllowNull extends true ? BaseType | undefined | null : BaseType | undefined);
|
4
16
|
type Awaitable<Type> = Type | Promise<Type>;
|
package/build/tsconfig.json
CHANGED
package/package.json
CHANGED
package/build/classy/logic.d.ts
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
import type { TCleanState, ExtractCleanStateData, TStateData } from '../base/state';
|
2
|
-
export type HardEmpty = HardEmptyObject;
|
3
|
-
export type WeakEmpty = WeakEmptyObject;
|
4
|
-
export type THooksBase = o | void;
|
5
|
-
type o = object;
|
6
|
-
/**
|
7
|
-
* Base class for a class that holds methods intended for use in a function component,
|
8
|
-
* as well as a static method for initializing state.
|
9
|
-
*
|
10
|
-
* These methods will have access to the components state and props via
|
11
|
-
* `this.state` and `this.props` respectively.
|
12
|
-
*
|
13
|
-
* The special {@link ComponentLogic.useHooks | useHooks} method allows you to consume
|
14
|
-
* React hooks within this class.
|
15
|
-
*
|
16
|
-
* Call the {@link useLogic} hook inside your function component to instantiate the class.
|
17
|
-
*/
|
18
|
-
export declare class ComponentLogic<
|
19
|
-
/** Describe the values your component expects to be passed as props. */
|
20
|
-
TProps extends object = {},
|
21
|
-
/** An object type that descibes your component's state. */
|
22
|
-
TState extends TStateData = WeakEmpty,
|
23
|
-
/** The object type returned by your component's {@link useHooks} method. */
|
24
|
-
THooks extends THooksBase = void> {
|
25
|
-
state: TCleanState<TState>;
|
26
|
-
readonly props: TProps;
|
27
|
-
readonly hooks: THooks extends object ? THooks : WeakEmptyObject;
|
28
|
-
/**
|
29
|
-
* Called before each instance of your component is mounted.
|
30
|
-
* It receives the initial `props` object and should return
|
31
|
-
* an object with the initial values for your component's state.
|
32
|
-
*/
|
33
|
-
static getInitialState: (p?: object) => object;
|
34
|
-
/**
|
35
|
-
* This allows you to seamlessly consume React hooks in
|
36
|
-
* your class component.
|
37
|
-
*
|
38
|
-
* It is called after state and props are updated on each render.
|
39
|
-
* Call any hooks (e.g `useEffect`) you which to consume inside this function.
|
40
|
-
*
|
41
|
-
* To expose any returned values from your hooks to the rest of your component,
|
42
|
-
* return an object that contains all the relevant values.
|
43
|
-
*
|
44
|
-
* This object will be accessible as `this.hooks` to the rest of your class.
|
45
|
-
*/
|
46
|
-
useHooks: THooks extends void ? undefined | (() => void | HardEmptyObject) : () => THooks;
|
47
|
-
}
|
48
|
-
type LogicClassParams = ConstructorParameters<typeof ComponentLogic>;
|
49
|
-
export interface IComponentLogicClass<Instance extends ComponentLogic<o, o, THooksBase> = ComponentLogic, Params extends LogicClassParams = LogicClassParams> extends Constructor<Instance, Params> {
|
50
|
-
getInitialState: (props?: Instance['props']) => ExtractCleanStateData<Instance['state']>;
|
51
|
-
}
|
52
|
-
type UseLogic = {
|
53
|
-
<Class extends typeof ComponentLogic<HardEmptyObject, o, THooksBase>>(Methods: Class & IComponentLogicClass<InstanceType<Class>>): InstanceType<Class>;
|
54
|
-
<Class extends typeof ComponentLogic<o, o, THooksBase>>(Methods: Class & IComponentLogicClass<InstanceType<Class>>, props: InstanceType<Class>['props']): InstanceType<Class>;
|
55
|
-
};
|
56
|
-
declare const useLogic: UseLogic;
|
57
|
-
export { useLogic };
|
package/build/classy/logic.js
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.useLogic = exports.ComponentLogic = void 0;
|
4
|
-
var react_1 = require("react");
|
5
|
-
var state_1 = require("../base/state");
|
6
|
-
/**
|
7
|
-
* Base class for a class that holds methods intended for use in a function component,
|
8
|
-
* as well as a static method for initializing state.
|
9
|
-
*
|
10
|
-
* These methods will have access to the components state and props via
|
11
|
-
* `this.state` and `this.props` respectively.
|
12
|
-
*
|
13
|
-
* The special {@link ComponentLogic.useHooks | useHooks} method allows you to consume
|
14
|
-
* React hooks within this class.
|
15
|
-
*
|
16
|
-
* Call the {@link useLogic} hook inside your function component to instantiate the class.
|
17
|
-
*/
|
18
|
-
var ComponentLogic = /** @class */ (function () {
|
19
|
-
function ComponentLogic() {
|
20
|
-
}
|
21
|
-
/**
|
22
|
-
* Called before each instance of your component is mounted.
|
23
|
-
* It receives the initial `props` object and should return
|
24
|
-
* an object with the initial values for your component's state.
|
25
|
-
*/
|
26
|
-
ComponentLogic.getInitialState = function (p) { return ({}); };
|
27
|
-
return ComponentLogic;
|
28
|
-
}());
|
29
|
-
exports.ComponentLogic = ComponentLogic;
|
30
|
-
;
|
31
|
-
var useLogic = function () {
|
32
|
-
var _a, _b;
|
33
|
-
var args = [];
|
34
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
35
|
-
args[_i] = arguments[_i];
|
36
|
-
}
|
37
|
-
var Logic = args[0], _c = args[1], props = _c === void 0 ? {} : _c;
|
38
|
-
var state = (0, state_1.useCleanState)(Logic.getInitialState, props);
|
39
|
-
var self = (0, react_1.useRef)((0, react_1.useMemo)(function () {
|
40
|
-
return new Logic();
|
41
|
-
}, [])).current;
|
42
|
-
/** A proxy variable to allow typechecking of the assignment to `self.props` despite the need for "readonly" error suppression. */
|
43
|
-
var _propsProxy_;
|
44
|
-
/** A proxy variable to allow typechecking of the assignment to `self.hooks` despite the need for "readonly" error suppression. */
|
45
|
-
var _hooksProxy_;
|
46
|
-
self.state = state;
|
47
|
-
// @ts-expect-error
|
48
|
-
self.props = (_propsProxy_ = props);
|
49
|
-
// @ts-expect-error
|
50
|
-
self.hooks = (_hooksProxy_ = (_b = (_a = self.useHooks) === null || _a === void 0 ? void 0 : _a.call(self)) !== null && _b !== void 0 ? _b : {} // @todo Improve UseLogic types to reflect that this may be undefined.
|
51
|
-
);
|
52
|
-
return self;
|
53
|
-
};
|
54
|
-
exports.useLogic = useLogic;
|
55
|
-
/*testing: {
|
56
|
-
const a: object = {b: ''};
|
57
|
-
|
58
|
-
type t = keyof typeof a;
|
59
|
-
|
60
|
-
class MyComponentLogic extends ComponentLogic<{a: string}> {
|
61
|
-
static getInitialState = () => ({a: '' as const});
|
62
|
-
// b = this.state.put[''] + this.props.b;
|
63
|
-
};
|
64
|
-
|
65
|
-
type tt = keyof {};
|
66
|
-
|
67
|
-
MyComponentLogic.getInitialState
|
68
|
-
// const self = useLogic(MyComponentLogic);
|
69
|
-
|
70
|
-
|
71
|
-
const A = class C extends ComponentLogic {
|
72
|
-
// static getInitialState = () => ({a: 'l'});
|
73
|
-
// a = () => this.state.yyy = '';
|
74
|
-
}
|
75
|
-
|
76
|
-
A.getInitialState();
|
77
|
-
|
78
|
-
// const oa = {['a' as unknown as symbol]: 'boo'};
|
79
|
-
const oa = {['a']: 'boo'};
|
80
|
-
// const self = useLogic(A, oa);
|
81
|
-
}*/
|