@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.
@@ -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 = {
@@ -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
- this._hmrPreserveKeys = [];
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
- var hmrPreserveKeys = __spreadArray(__spreadArray([], latestInstance._hmrPreserveKeys, true), [
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<TPropsBase>>;
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
- var hmrPreserveKeys = __spreadArray(__spreadArray([], latestInstance._hmrPreserveKeys, true), [
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, TPropsBase } from '..';
1
+ import type { ComponentLogic } from '..';
2
2
  /*************************************
3
3
  * # Hooks *
4
4
  **************************************/
5
- type ULClassParam = typeof ComponentLogic<NonNullable<TPropsBase>>;
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",
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 && npm run build:docs",
28
+ "postbuild": "copyfiles tsconfig.json build",
29
29
  "build:docs": "typedoc",
30
30
  "_": "",
31
31
  "prepublishOnly": "npm run build",