@cleanweb/react 2.1.3 → 2.1.5
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/methods.d.ts +74 -0
- package/build/base/methods.js +50 -14
- package/build/base/state/hook-types.d.ts +0 -4
- package/build/classy/instance/types/hook.d.ts +1 -2
- package/build/classy/logic/index.d.ts +74 -3
- package/build/classy/logic/index.js +49 -16
- package/build/classy/logic/types/hook.d.ts +2 -2
- package/package.json +3 -3
package/build/base/methods.d.ts
CHANGED
@@ -15,7 +15,81 @@ import type { TCleanState, TStateData } from './state';
|
|
15
15
|
export declare class ComponentMethods<TProps extends object = {}, TState extends TStateData | null = null> {
|
16
16
|
readonly props: TProps;
|
17
17
|
readonly state: TState extends TStateData ? TCleanState<TState> : null;
|
18
|
+
/**
|
19
|
+
* Specify custom class members to be copied over whenever the class is
|
20
|
+
* reinstantiated during hot module replacement.
|
21
|
+
*
|
22
|
+
* Oore handles HMR by recreating the class instance
|
23
|
+
* with the updated code whenever there is a file change.
|
24
|
+
* Your component is then rerendered so that event handlers
|
25
|
+
* now point to the new functions.
|
26
|
+
*
|
27
|
+
* For this to work well, your component's state needs to be preserved,
|
28
|
+
* so it is copied over from the old instance, to the newly created one.
|
29
|
+
* This includes `state`, `props` by default, but you can
|
30
|
+
* extend it to include more properties if there are values your component expects
|
31
|
+
* to be persistent.
|
32
|
+
*
|
33
|
+
* In most case, any values you wish to preserve should be created `React.useRef`.
|
34
|
+
* ```
|
35
|
+
* // In useHooks method:
|
36
|
+
* this.inputId = useRef(inputId);
|
37
|
+
* // And access anywhere with:
|
38
|
+
* this.inputId.current;
|
39
|
+
* ```
|
40
|
+
* If you use a ref in this way, React will preserve it for you, and there will be no need
|
41
|
+
* to use `_hmrPreserveKeys`.
|
42
|
+
*
|
43
|
+
* `_hmrPreserveKeys` is only relevant in development and has not effect in production environment.
|
44
|
+
* Accordingly, you should only update this array when environment is development, so
|
45
|
+
* that it can be tree-shaken during production builds.
|
46
|
+
*
|
47
|
+
* @example Specify additional properties to be considered stateful,
|
48
|
+
* in addition to `state`, `props`, and `hooks`.
|
49
|
+
* ```ts
|
50
|
+
* MyComponentMethods extends ComponentMethods {
|
51
|
+
* // Some class member definitions...
|
52
|
+
*
|
53
|
+
* constructor() {
|
54
|
+
* if (process.env.NODE_ENV === 'development') {
|
55
|
+
* this._hmrPreserveKeys.push('inputId', 'unsubscribeCallback');
|
56
|
+
* }
|
57
|
+
* }
|
58
|
+
*
|
59
|
+
* // Method definitions...
|
60
|
+
* }
|
61
|
+
* With the above example, whenever HMR occurs, `this.inputId` and `this.unsubscribeCallback`
|
62
|
+
* will maintain there existing values, while everything else will be recreated. Meanwhile,
|
63
|
+
* because the code is written in an environment condition, it should be easy to strip it from the
|
64
|
+
* production build to avoid shipping dead code.
|
65
|
+
*/
|
18
66
|
_hmrPreserveKeys: Array<keyof this | (string & {})>;
|
67
|
+
/**
|
68
|
+
* Handle complex update logic whenever your component instance is updated through HMR.
|
69
|
+
* The function is called on the new instance, and it receives the old instance as the only argument.
|
70
|
+
* So you can access data from the old instance, and reinitialize any processes on the new instance as needed.
|
71
|
+
*
|
72
|
+
*
|
73
|
+
* `_onHmrUpdate` is only relevant in development and has not effect in production environment.
|
74
|
+
* Accordingly, you should only assign this function when environment is development, so
|
75
|
+
* that it can be tree-shaken during production builds.
|
76
|
+
*
|
77
|
+
* @example
|
78
|
+
* ```ts
|
79
|
+
* MyComponentMethods extends ComponentMethods {
|
80
|
+
* // Some class member definitions...
|
81
|
+
*
|
82
|
+
* constructor() {
|
83
|
+
* if (process.env.NODE_ENV === 'development') {
|
84
|
+
* this._onHmrUpdate = () => {
|
85
|
+
* // Your custom hmr logic here.
|
86
|
+
* };
|
87
|
+
* }
|
88
|
+
* }
|
89
|
+
*
|
90
|
+
* // Method definitions...
|
91
|
+
* }
|
92
|
+
*/
|
19
93
|
_onHmrUpdate?: <TInstance extends this>(oldInstance: TInstance) => void;
|
20
94
|
}
|
21
95
|
type UseMethods = {
|
package/build/base/methods.js
CHANGED
@@ -2,15 +2,6 @@
|
|
2
2
|
/**
|
3
3
|
* @module ComponentMethods
|
4
4
|
*/
|
5
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
6
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
7
|
-
if (ar || !(i in from)) {
|
8
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
9
|
-
ar[i] = from[i];
|
10
|
-
}
|
11
|
-
}
|
12
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
13
|
-
};
|
14
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
15
6
|
exports.useMethods = exports.ComponentMethods = void 0;
|
16
7
|
// JSDoc references
|
@@ -29,7 +20,55 @@ var react_1 = require("react");
|
|
29
20
|
*/
|
30
21
|
var ComponentMethods = /** @class */ (function () {
|
31
22
|
function ComponentMethods() {
|
32
|
-
|
23
|
+
/**
|
24
|
+
* Specify custom class members to be copied over whenever the class is
|
25
|
+
* reinstantiated during hot module replacement.
|
26
|
+
*
|
27
|
+
* Oore handles HMR by recreating the class instance
|
28
|
+
* with the updated code whenever there is a file change.
|
29
|
+
* Your component is then rerendered so that event handlers
|
30
|
+
* now point to the new functions.
|
31
|
+
*
|
32
|
+
* For this to work well, your component's state needs to be preserved,
|
33
|
+
* so it is copied over from the old instance, to the newly created one.
|
34
|
+
* This includes `state`, `props` by default, but you can
|
35
|
+
* extend it to include more properties if there are values your component expects
|
36
|
+
* to be persistent.
|
37
|
+
*
|
38
|
+
* In most case, any values you wish to preserve should be created `React.useRef`.
|
39
|
+
* ```
|
40
|
+
* // In useHooks method:
|
41
|
+
* this.inputId = useRef(inputId);
|
42
|
+
* // And access anywhere with:
|
43
|
+
* this.inputId.current;
|
44
|
+
* ```
|
45
|
+
* If you use a ref in this way, React will preserve it for you, and there will be no need
|
46
|
+
* to use `_hmrPreserveKeys`.
|
47
|
+
*
|
48
|
+
* `_hmrPreserveKeys` is only relevant in development and has not effect in production environment.
|
49
|
+
* Accordingly, you should only update this array when environment is development, so
|
50
|
+
* that it can be tree-shaken during production builds.
|
51
|
+
*
|
52
|
+
* @example Specify additional properties to be considered stateful,
|
53
|
+
* in addition to `state`, `props`, and `hooks`.
|
54
|
+
* ```ts
|
55
|
+
* MyComponentMethods extends ComponentMethods {
|
56
|
+
* // Some class member definitions...
|
57
|
+
*
|
58
|
+
* constructor() {
|
59
|
+
* if (process.env.NODE_ENV === 'development') {
|
60
|
+
* this._hmrPreserveKeys.push('inputId', 'unsubscribeCallback');
|
61
|
+
* }
|
62
|
+
* }
|
63
|
+
*
|
64
|
+
* // Method definitions...
|
65
|
+
* }
|
66
|
+
* With the above example, whenever HMR occurs, `this.inputId` and `this.unsubscribeCallback`
|
67
|
+
* will maintain there existing values, while everything else will be recreated. Meanwhile,
|
68
|
+
* because the code is written in an environment condition, it should be easy to strip it from the
|
69
|
+
* production build to avoid shipping dead code.
|
70
|
+
*/
|
71
|
+
this._hmrPreserveKeys = []; // @todo Keep undefined. Update to empty array after instantiation in dev env.
|
33
72
|
}
|
34
73
|
return ComponentMethods;
|
35
74
|
}());
|
@@ -72,10 +111,7 @@ var useMethods = function () {
|
|
72
111
|
'all clean-react hooks receive the same class argument on every render.'
|
73
112
|
].join(' '));
|
74
113
|
var oldInstance = instanceRef.current;
|
75
|
-
|
76
|
-
'state', 'props',
|
77
|
-
], false);
|
78
|
-
hmrPreserveKeys.forEach(function (_key) {
|
114
|
+
latestInstance._hmrPreserveKeys.forEach(function (_key) {
|
79
115
|
var key = _key;
|
80
116
|
// @ts-expect-error We're assigning to readonly properties. Also, Typescript doesn't know that the type of the left and right side will always match, due to the dynamic access.
|
81
117
|
latestInstance[key] = oldInstance[key];
|
@@ -2,8 +2,6 @@ import { CleanStateBase } from './class';
|
|
2
2
|
/**
|
3
3
|
* Base type for an `initialState` object.
|
4
4
|
* It is a regular object type, with some reserved keys excluded.
|
5
|
-
*
|
6
|
-
* @_category Types
|
7
5
|
*/
|
8
6
|
export type TStateData = object & {
|
9
7
|
[Key in keyof CleanStateBase<{}>]?: never;
|
@@ -13,8 +11,6 @@ export type TStateData = object & {
|
|
13
11
|
* object of type `TState`.
|
14
12
|
*
|
15
13
|
* @typeParam TState - The type of your `initialState` object.
|
16
|
-
*
|
17
|
-
* @_category Types
|
18
14
|
*/
|
19
15
|
export type TCleanState<TState extends TStateData> = (CleanStateBase<TState> & Omit<TState, keyof CleanStateBase<{}>>);
|
20
16
|
/**
|
@@ -1,6 +1,5 @@
|
|
1
|
-
import { TPropsBase } from '../../../classy/logic';
|
2
1
|
import { ComponentInstance } from '..';
|
3
|
-
type UIClassParam = typeof ComponentInstance<NonNullable<
|
2
|
+
type UIClassParam = typeof ComponentInstance<NonNullable<any>>;
|
4
3
|
type UIProplessClassParam = typeof ComponentInstance<null>;
|
5
4
|
export type UseInstance = {
|
6
5
|
<Class extends UIProplessClassParam>(Methods: Class): InstanceType<Class>;
|
@@ -23,9 +23,6 @@ export type TPropsBase = NonPrimitive | null;
|
|
23
23
|
* Call the {@link useLogic} hook inside your function component to instantiate the class.
|
24
24
|
*
|
25
25
|
* @typeParam TProps - {@include ./types/tprops.md}
|
26
|
-
*
|
27
|
-
* @group ComponentLogic
|
28
|
-
* @_category External Classes
|
29
26
|
*/
|
30
27
|
export declare class ComponentLogic<TProps extends TPropsBase = null> {
|
31
28
|
/**
|
@@ -58,7 +55,81 @@ export declare class ComponentLogic<TProps extends TPropsBase = null> {
|
|
58
55
|
* your component class.
|
59
56
|
*/
|
60
57
|
useHooks: () => object | void;
|
58
|
+
/**
|
59
|
+
* Specify custom class members to be copied over whenever the class is
|
60
|
+
* reinstantiated during hot module replacement.
|
61
|
+
*
|
62
|
+
* Oore handles HMR by recreating the class instance
|
63
|
+
* with the updated code whenever there is a file change.
|
64
|
+
* Your component is then rerendered so that event handlers
|
65
|
+
* now point to the new functions.
|
66
|
+
*
|
67
|
+
* For this to work well, your component's state needs to be preserved,
|
68
|
+
* so it is copied over from the old instance, to the newly created one.
|
69
|
+
* This includes `state`, `props` by default, but you can
|
70
|
+
* extend it to include more properties if there are values your component expects
|
71
|
+
* to be persistent.
|
72
|
+
*
|
73
|
+
* In most case, any values you wish to preserve should be created `React.useRef`.
|
74
|
+
* ```
|
75
|
+
* // In useHooks method:
|
76
|
+
* this.inputId = useRef(inputId);
|
77
|
+
* // And access anywhere with:
|
78
|
+
* this.inputId.current;
|
79
|
+
* ```
|
80
|
+
* If you use a ref in this way, React will preserve it for you, and there will be no need
|
81
|
+
* to use `_hmrPreserveKeys`.
|
82
|
+
*
|
83
|
+
* `_hmrPreserveKeys` is only relevant in development and has not effect in production environment.
|
84
|
+
* Accordingly, you should only update this array when environment is development, so
|
85
|
+
* that it can be tree-shaken during production builds.
|
86
|
+
*
|
87
|
+
* @example Specify additional properties to be considered stateful,
|
88
|
+
* in addition to `state`, `props`, and `hooks`.
|
89
|
+
* ```ts
|
90
|
+
* MyComponentMethods extends ComponentMethods {
|
91
|
+
* // Some class member definitions...
|
92
|
+
*
|
93
|
+
* constructor() {
|
94
|
+
* if (process.env.NODE_ENV === 'development') {
|
95
|
+
* this._hmrPreserveKeys.push('inputId', 'unsubscribeCallback');
|
96
|
+
* }
|
97
|
+
* }
|
98
|
+
*
|
99
|
+
* // Method definitions...
|
100
|
+
* }
|
101
|
+
* With the above example, whenever HMR occurs, `this.inputId` and `this.unsubscribeCallback`
|
102
|
+
* will maintain there existing values, while everything else will be recreated. Meanwhile,
|
103
|
+
* because the code is written in an environment condition, it should be easy to strip it from the
|
104
|
+
* production build to avoid shipping dead code.
|
105
|
+
*/
|
61
106
|
_hmrPreserveKeys: Array<keyof this | (string & {})>;
|
107
|
+
/**
|
108
|
+
* Handle complex update logic whenever your component instance is updated through HMR.
|
109
|
+
* The function is called on the new instance, and it receives the old instance as the only argument.
|
110
|
+
* So you can access data from the old instance, and reinitialize any processes on the new instance as needed.
|
111
|
+
*
|
112
|
+
*
|
113
|
+
* `_onHmrUpdate` is only relevant in development and has not effect in production environment.
|
114
|
+
* Accordingly, you should only assign this function when environment is development, so
|
115
|
+
* that it can be tree-shaken during production builds.
|
116
|
+
*
|
117
|
+
* @example
|
118
|
+
* ```ts
|
119
|
+
* MyComponentMethods extends ComponentMethods {
|
120
|
+
* // Some class member definitions...
|
121
|
+
*
|
122
|
+
* constructor() {
|
123
|
+
* if (process.env.NODE_ENV === 'development') {
|
124
|
+
* this._onHmrUpdate = () => {
|
125
|
+
* // Your custom hmr logic here.
|
126
|
+
* };
|
127
|
+
* }
|
128
|
+
* }
|
129
|
+
*
|
130
|
+
* // Method definitions...
|
131
|
+
* }
|
132
|
+
*/
|
62
133
|
_onHmrUpdate?: <TInstance extends this>(oldInstance: TInstance) => void;
|
63
134
|
}
|
64
135
|
/**
|
@@ -1,13 +1,4 @@
|
|
1
1
|
"use strict";
|
2
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
3
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
4
|
-
if (ar || !(i in from)) {
|
5
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
6
|
-
ar[i] = from[i];
|
7
|
-
}
|
8
|
-
}
|
9
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
10
|
-
};
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
12
3
|
exports.useLogic = exports.ComponentLogic = void 0;
|
13
4
|
var react_1 = require("react");
|
@@ -25,9 +16,6 @@ var state_1 = require("../../base/state");
|
|
25
16
|
* Call the {@link useLogic} hook inside your function component to instantiate the class.
|
26
17
|
*
|
27
18
|
* @typeParam TProps - {@include ./types/tprops.md}
|
28
|
-
*
|
29
|
-
* @group ComponentLogic
|
30
|
-
* @_category External Classes
|
31
19
|
*/
|
32
20
|
var ComponentLogic = /** @class */ (function () {
|
33
21
|
function ComponentLogic() {
|
@@ -46,6 +34,54 @@ var ComponentLogic = /** @class */ (function () {
|
|
46
34
|
* your component class.
|
47
35
|
*/
|
48
36
|
this.useHooks = function () { };
|
37
|
+
/**
|
38
|
+
* Specify custom class members to be copied over whenever the class is
|
39
|
+
* reinstantiated during hot module replacement.
|
40
|
+
*
|
41
|
+
* Oore handles HMR by recreating the class instance
|
42
|
+
* with the updated code whenever there is a file change.
|
43
|
+
* Your component is then rerendered so that event handlers
|
44
|
+
* now point to the new functions.
|
45
|
+
*
|
46
|
+
* For this to work well, your component's state needs to be preserved,
|
47
|
+
* so it is copied over from the old instance, to the newly created one.
|
48
|
+
* This includes `state`, `props` by default, but you can
|
49
|
+
* extend it to include more properties if there are values your component expects
|
50
|
+
* to be persistent.
|
51
|
+
*
|
52
|
+
* In most case, any values you wish to preserve should be created `React.useRef`.
|
53
|
+
* ```
|
54
|
+
* // In useHooks method:
|
55
|
+
* this.inputId = useRef(inputId);
|
56
|
+
* // And access anywhere with:
|
57
|
+
* this.inputId.current;
|
58
|
+
* ```
|
59
|
+
* If you use a ref in this way, React will preserve it for you, and there will be no need
|
60
|
+
* to use `_hmrPreserveKeys`.
|
61
|
+
*
|
62
|
+
* `_hmrPreserveKeys` is only relevant in development and has not effect in production environment.
|
63
|
+
* Accordingly, you should only update this array when environment is development, so
|
64
|
+
* that it can be tree-shaken during production builds.
|
65
|
+
*
|
66
|
+
* @example Specify additional properties to be considered stateful,
|
67
|
+
* in addition to `state`, `props`, and `hooks`.
|
68
|
+
* ```ts
|
69
|
+
* MyComponentMethods extends ComponentMethods {
|
70
|
+
* // Some class member definitions...
|
71
|
+
*
|
72
|
+
* constructor() {
|
73
|
+
* if (process.env.NODE_ENV === 'development') {
|
74
|
+
* this._hmrPreserveKeys.push('inputId', 'unsubscribeCallback');
|
75
|
+
* }
|
76
|
+
* }
|
77
|
+
*
|
78
|
+
* // Method definitions...
|
79
|
+
* }
|
80
|
+
* With the above example, whenever HMR occurs, `this.inputId` and `this.unsubscribeCallback`
|
81
|
+
* will maintain there existing values, while everything else will be recreated. Meanwhile,
|
82
|
+
* because the code is written in an environment condition, it should be easy to strip it from the
|
83
|
+
* production build to avoid shipping dead code.
|
84
|
+
*/
|
49
85
|
this._hmrPreserveKeys = [];
|
50
86
|
}
|
51
87
|
return ComponentLogic;
|
@@ -84,10 +120,7 @@ var useLogic = function () {
|
|
84
120
|
'all clean-react hooks receive the same class argument on every render.'
|
85
121
|
].join(' '));
|
86
122
|
var oldInstance_1 = instanceRef.current;
|
87
|
-
|
88
|
-
'state', 'props', 'hooks',
|
89
|
-
], false);
|
90
|
-
hmrPreserveKeys.forEach(function (_key) {
|
123
|
+
latestInstance._hmrPreserveKeys.forEach(function (_key) {
|
91
124
|
var key = _key;
|
92
125
|
// @ts-expect-error We're assigning to readonly properties. Also, Typescript doesn't know that the type of the left and right side will always match, due to the dynamic access.
|
93
126
|
latestInstance[key] = oldInstance_1[key];
|
@@ -1,8 +1,8 @@
|
|
1
|
-
import type { ComponentLogic
|
1
|
+
import type { ComponentLogic } from '..';
|
2
2
|
/*************************************
|
3
3
|
* # Hooks *
|
4
4
|
**************************************/
|
5
|
-
type ULClassParam = typeof ComponentLogic<NonNullable<
|
5
|
+
type ULClassParam = typeof ComponentLogic<NonNullable<any>>;
|
6
6
|
type ULProplessClassParam = typeof ComponentLogic<null>;
|
7
7
|
export type UseLogic = {
|
8
8
|
<Class extends ULProplessClassParam>(Methods: Class): InstanceType<Class>;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@cleanweb/react",
|
3
|
-
"version": "2.1.
|
3
|
+
"version": "2.1.5",
|
4
4
|
"description": "A suite of helpers for writing cleaner React function components.",
|
5
5
|
"engines": {
|
6
6
|
"node": ">=18"
|
@@ -22,10 +22,10 @@
|
|
22
22
|
"./all": "./build/index.js"
|
23
23
|
},
|
24
24
|
"scripts": {
|
25
|
-
"prebuild": "rimraf ./build",
|
25
|
+
"prebuild": "rimraf ./build && npm run build:docs",
|
26
26
|
"build": "tsc && tsc-alias",
|
27
27
|
"serve-docs": "serve docs",
|
28
|
-
"postbuild": "copyfiles tsconfig.json build
|
28
|
+
"postbuild": "copyfiles tsconfig.json build",
|
29
29
|
"build:docs": "typedoc",
|
30
30
|
"_": "",
|
31
31
|
"prepublishOnly": "npm run build",
|