@cleanweb/react 1.1.1-beta.9 → 2.1.0-beta.0

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.
Files changed (58) hide show
  1. package/README.md +242 -187
  2. package/README.old.md +342 -0
  3. package/build/base/index.d.ts +1 -0
  4. package/build/base/index.js +1 -0
  5. package/build/base/merged-state.d.ts +1 -0
  6. package/build/base/merged-state.js +3 -2
  7. package/build/base/methods.d.ts +39 -6
  8. package/build/base/methods.js +45 -80
  9. package/build/base/state/class-types.d.ts +17 -0
  10. package/build/base/state/class-types.js +2 -0
  11. package/build/base/state/class.d.ts +14 -0
  12. package/build/base/{state.js → state/class.js} +4 -51
  13. package/build/base/state/hook-types.d.ts +12 -0
  14. package/build/base/state/hook-types.js +2 -0
  15. package/build/base/state/hooks.d.ts +6 -0
  16. package/build/base/state/hooks.js +39 -0
  17. package/build/base/state/index.d.ts +4 -0
  18. package/build/base/state/index.js +8 -0
  19. package/build/classy/class/index.d.ts +83 -0
  20. package/build/classy/class/index.js +149 -0
  21. package/build/classy/class/types/extractor.d.ts +5 -0
  22. package/build/classy/class/types/extractor.js +2 -0
  23. package/build/classy/class/utils/function-name.d.ts +2 -0
  24. package/build/classy/class/utils/function-name.js +17 -0
  25. package/build/classy/class/utils/rerender.d.ts +1 -0
  26. package/build/classy/class/utils/rerender.js +23 -0
  27. package/build/classy/class/utils/use-component/index.d.ts +6 -0
  28. package/build/classy/class/utils/use-component/index.js +17 -0
  29. package/build/classy/class/utils/use-component/types.d.ts +22 -0
  30. package/build/classy/class/utils/use-component/types.js +2 -0
  31. package/build/classy/instance/index.d.ts +64 -0
  32. package/build/classy/{instance.js → instance/index.js} +53 -42
  33. package/build/classy/instance/mount-callbacks.d.ts +4 -0
  34. package/build/classy/instance/mount-callbacks.js +30 -0
  35. package/build/classy/instance/types/hook.d.ts +13 -0
  36. package/build/classy/instance/types/hook.js +2 -0
  37. package/build/classy/logic/index.d.ts +48 -0
  38. package/build/classy/logic/index.js +113 -0
  39. package/build/classy/logic/types/hook.d.ts +17 -0
  40. package/build/classy/logic/types/hook.js +2 -0
  41. package/build/globals.d.ts +49 -33
  42. package/build/globals.js +2 -20
  43. package/build/helpers/index.d.ts +1 -0
  44. package/build/helpers/index.js +17 -0
  45. package/build/helpers/mount-state.d.ts +5 -0
  46. package/build/helpers/mount-state.js +25 -0
  47. package/build/index.d.ts +3 -1
  48. package/build/index.js +3 -15
  49. package/build/tsconfig.json +3 -0
  50. package/package.json +4 -11
  51. package/build/base/state.d.ts +0 -31
  52. package/build/classy/class.d.ts +0 -24
  53. package/build/classy/class.js +0 -132
  54. package/build/classy/instance.d.ts +0 -61
  55. package/build/classy/logic.d.ts +0 -20
  56. package/build/classy/logic.js +0 -82
  57. package/build/globals.private.d.ts +0 -44
  58. package/build/globals.private.js +0 -34
@@ -15,68 +15,52 @@ var __extends = (this && this.__extends) || (function () {
15
15
  };
16
16
  })();
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.useInstance = exports.ComponentInstance = exports.noOp = exports.useMountCallbacks = void 0;
18
+ exports.useInstance = exports.ComponentInstance = exports.noOp = void 0;
19
19
  var react_1 = require("react");
20
- var state_1 = require("../base/state");
21
- var logic_1 = require("./logic");
22
- var useMountCallbacks = function (instance) {
23
- var _a;
24
- var mounted = (0, state_1.useMountState)();
25
- if (!mounted)
26
- (_a = instance.beforeMount) === null || _a === void 0 ? void 0 : _a.call(instance);
27
- (0, react_1.useEffect)(function () {
28
- var _a;
29
- var mountHandlerCleanUp = (_a = instance.onMount) === null || _a === void 0 ? void 0 : _a.call(instance);
30
- return function () {
31
- var doCleanUp = function (runMountCleaners) {
32
- var _a;
33
- runMountCleaners === null || runMountCleaners === void 0 ? void 0 : runMountCleaners();
34
- // onDismount? willUnmount?
35
- (_a = instance.cleanUp) === null || _a === void 0 ? void 0 : _a.call(instance);
36
- };
37
- if (typeof mountHandlerCleanUp === 'function') {
38
- doCleanUp(mountHandlerCleanUp);
39
- }
40
- else {
41
- mountHandlerCleanUp === null || mountHandlerCleanUp === void 0 ? void 0 : mountHandlerCleanUp.then(doCleanUp);
42
- }
43
- };
44
- }, []);
45
- };
46
- exports.useMountCallbacks = useMountCallbacks;
20
+ var logic_1 = require("../../classy/logic");
21
+ var mount_callbacks_1 = require("./mount-callbacks");
22
+ /** An empty function. It returns (void) without performing any operations. */
47
23
  var noOp = function () { };
48
24
  exports.noOp = noOp;
25
+ /**
26
+ * A superset of {@link ComponentLogic} that adds support for lifecycle methods.
27
+ * This provides a declarative API for working with your React function component's lifecycle,
28
+ * a simpler alternative to the imperative approach with `useEffect` and/or `useMemo`.
29
+ *
30
+ * @see https://github.com/cleanjsweb/neat-react#lifecycle-useinstance
31
+ */
49
32
  var ComponentInstance = /** @class */ (function (_super) {
50
33
  __extends(ComponentInstance, _super);
51
34
  function ComponentInstance() {
52
35
  var _this = _super !== null && _super.apply(this, arguments) || this;
53
36
  /**
54
- * Runs only _before_ first render, i.e before the component instance is mounted.
55
- * Useful for logic that is involved in determining what to render.
37
+ * Runs only _before_ first render,
38
+ * i.e before the component instance is mounted.
56
39
  *
57
- * Updating local state from in here will abort the render cycle early, before changes are committed to the DOM,
58
- * and prompt React to immediately rerender the component with the updated state value(s).
40
+ * It is ignored on subsequent rerenders.
59
41
  *
60
- * Ignored on subsequent rerenders.
42
+ * PS: You can conditionally update state from here, but with certain caveats.
43
+ * {@link https://react.dev/reference/react/useState#storing-information-from-previous-renders | See the React docs for more details}.
61
44
  */
62
45
  _this.beforeMount = function () { };
63
46
  /**
64
47
  * Runs only **_after_** first render, i.e after the component instance is mounted.
48
+ * It is ignored on subsequent rerenders.
65
49
  *
66
50
  * Should usually only be used for logic that does not directly take part in determining what to render, like
67
51
  * synchronize your component with some external system.
68
52
  *
69
- * Ignored on subsequent rerenders.
53
+ * @returns A cleanup function.
70
54
  *
71
- * Returns a cleanup function.
55
+ * Uses `useEffect()` under the hood.
72
56
  */
73
57
  _this.onMount = function () { return exports.noOp; };
74
58
  /**
75
59
  * Runs _before_ every render cycle, including the first.
76
60
  * Useful for logic that is involved in determining what to render.
77
61
  *
78
- * Updating local state from in here will abort the render cycle early, before changes are committed to the DOM,
79
- * and prompt React to immediately rerender the component with the updated state value(s).
62
+ * PS: You can conditionally update state from here, but with certain caveats.
63
+ * {@link https://react.dev/reference/react/useState#storing-information-from-previous-renders | See the React docs for more details}.
80
64
  */
81
65
  _this.beforeRender = function () { };
82
66
  /**
@@ -85,6 +69,8 @@ var ComponentInstance = /** @class */ (function (_super) {
85
69
  * Should usually only be used for logic that does not directly take part in determining what to render, like
86
70
  * synchronize your component with some external system.
87
71
  *
72
+ * Uses `useEffect()` under the hood.
73
+ *
88
74
  * Returns a cleanup function.
89
75
  */
90
76
  _this.onRender = function () { return exports.noOp; };
@@ -95,11 +81,17 @@ var ComponentInstance = /** @class */ (function (_super) {
95
81
  _this.cleanUp = function () { };
96
82
  return _this;
97
83
  }
84
+ Object.defineProperty(ComponentInstance.prototype, "templateContext", {
85
+ get: function () {
86
+ return this._templateContext;
87
+ },
88
+ enumerable: false,
89
+ configurable: true
90
+ });
98
91
  return ComponentInstance;
99
92
  }(logic_1.ComponentLogic));
100
93
  exports.ComponentInstance = ComponentInstance;
101
94
  ;
102
- ;
103
95
  /*
104
96
  * To ensure successful type checking, the second parameter must be written with spread syntax.
105
97
  * Likely because of the `exactOptionalPropertyTypes` config option turned on,
@@ -117,7 +109,7 @@ var useInstance = function () {
117
109
  }
118
110
  var Component = args[0], _b = args[1], props = _b === void 0 ? {} : _b;
119
111
  // useHooks.
120
- var instance = (0, logic_1.useLogic)(Component, props); // Must spread rest parameter, rather than passing a single `props` argument directly.
112
+ var instance = (0, logic_1.useLogic)(Component, props);
121
113
  /**
122
114
  * Argument of type '
123
115
  * [
@@ -133,9 +125,15 @@ var useInstance = function () {
133
125
  '
134
126
  */
135
127
  // beforeMount, onMount, cleanUp.
136
- (0, exports.useMountCallbacks)(instance);
128
+ (0, mount_callbacks_1.useMountCallbacks)(instance);
137
129
  // beforeRender.
138
- (_a = instance.beforeRender) === null || _a === void 0 ? void 0 : _a.call(instance);
130
+ /**
131
+ * A proxy variable to allow typechecking of the assignment
132
+ * to `self.templateContext` despite the need for "readonly" error suppression.
133
+ */
134
+ var _templateContextProxy_;
135
+ // @ts-expect-error
136
+ instance._templateContext = (_templateContextProxy_ = (_a = instance.beforeRender) === null || _a === void 0 ? void 0 : _a.call(instance));
139
137
  // onRender.
140
138
  (0, react_1.useEffect)(function () {
141
139
  var _a;
@@ -150,12 +148,25 @@ var useInstance = function () {
150
148
  return instance;
151
149
  };
152
150
  exports.useInstance = useInstance;
151
+ /**/
153
152
  testing: {
154
153
  var A = /** @class */ (function (_super) {
155
154
  __extends(A, _super);
156
155
  function A() {
157
- return _super !== null && _super.apply(this, arguments) || this;
156
+ var _this = _super !== null && _super.apply(this, arguments) || this;
157
+ _this.getInitialState = function (p) { return ({ putan: '' }); };
158
+ // k = this.props.o
159
+ _this.am = _this.state['_initialValues_'];
160
+ _this.k = _this.am.putan;
161
+ _this.beforeRender = function () { return ({ g: '' }); };
162
+ _this.useHooks = function () {
163
+ return { j: 9 };
164
+ };
165
+ return _this;
158
166
  }
159
167
  return A;
160
168
  }(ComponentInstance));
169
+ var a = (0, exports.useInstance)(A, {});
170
+ a.am;
161
171
  }
172
+ /**/
@@ -0,0 +1,4 @@
1
+ import { ComponentInstance } from '.';
2
+ type UseMountCallbacks = <TInstance extends ComponentInstance>(instance: TInstance) => void;
3
+ export declare const useMountCallbacks: UseMountCallbacks;
4
+ export {};
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useMountCallbacks = void 0;
4
+ var react_1 = require("react");
5
+ var mount_state_1 = require("../../helpers/mount-state");
6
+ var useMountCallbacks = function (instance) {
7
+ var _a;
8
+ var isMounted = (0, mount_state_1.useMountState)();
9
+ if (!isMounted())
10
+ (_a = instance.beforeMount) === null || _a === void 0 ? void 0 : _a.call(instance);
11
+ (0, react_1.useEffect)(function () {
12
+ var _a;
13
+ var mountHandlerCleanUp = (_a = instance.onMount) === null || _a === void 0 ? void 0 : _a.call(instance);
14
+ return function () {
15
+ var doCleanUp = function (runMountCleaners) {
16
+ var _a;
17
+ runMountCleaners === null || runMountCleaners === void 0 ? void 0 : runMountCleaners();
18
+ // onDismount? willUnmount?
19
+ (_a = instance.cleanUp) === null || _a === void 0 ? void 0 : _a.call(instance);
20
+ };
21
+ if (typeof mountHandlerCleanUp === 'function') {
22
+ doCleanUp(mountHandlerCleanUp);
23
+ }
24
+ else {
25
+ mountHandlerCleanUp === null || mountHandlerCleanUp === void 0 ? void 0 : mountHandlerCleanUp.then(doCleanUp);
26
+ }
27
+ };
28
+ }, []);
29
+ };
30
+ exports.useMountCallbacks = useMountCallbacks;
@@ -0,0 +1,13 @@
1
+ import { ComponentInstance } from '..';
2
+ type UIClassParam = typeof ComponentInstance<object>;
3
+ type UIProplessClassParam = typeof ComponentInstance<HardEmptyObject>;
4
+ export type UseInstance = {
5
+ <Class extends UIProplessClassParam>(Methods: Class): InstanceType<Class>;
6
+ <Class extends UIClassParam>(Methods: Class, props: InstanceType<Class>['props']): InstanceType<Class>;
7
+ };
8
+ export type UIParams = [
9
+ Class: typeof ComponentInstance,
10
+ props?: object
11
+ ];
12
+ export type UIReturn = ComponentInstance;
13
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,48 @@
1
+ import type { TCleanState } from '../../base/state';
2
+ import type { UseLogic } from './types/hook';
3
+ export type HardEmpty = HardEmptyObject;
4
+ export type WeakEmpty = WeakEmptyObject;
5
+ /**
6
+ * Base class for a class that holds methods intended for use in a function component,
7
+ * as well as a static method for initializing state.
8
+ *
9
+ * These methods will have access to the components state and props via
10
+ * `this.state` and `this.props` respectively.
11
+ *
12
+ * The special {@link Class['useHooks'] | useHooks} method allows you to consume
13
+ * React hooks within this class.
14
+ *
15
+ * Call the {@link useLogic} hook inside your function component to instantiate the class.
16
+ */
17
+ export declare class ComponentLogic<TProps extends object = {}> {
18
+ /**
19
+ * A {@link TCleanState | `CleanState`} object.
20
+ * Holds all of your component's state,
21
+ * and methods for conveniently manipulating those values.
22
+ */
23
+ readonly state: TCleanState<ReturnType<this['getInitialState']>>;
24
+ /** The props pass into your component at the time of rendering. */
25
+ readonly props: TProps;
26
+ /**
27
+ * Values received from the hooks your component consumes.
28
+ * This holds the latest copy of the object returned by
29
+ * {@link useHooks}.
30
+ */
31
+ readonly hooks: ReturnType<this['useHooks']>;
32
+ /**
33
+ * Called before each instance of your component is mounted.
34
+ * It receives the initial `props` object and should return
35
+ * an object with the initial values for your component's state.
36
+ */
37
+ getInitialState: (props?: TProps) => object;
38
+ /**
39
+ * Call React hooks from here. If your component needs
40
+ * access to values return from the hooks you call,
41
+ * expose those values by returning an object with said values.
42
+ *
43
+ * The returned object will be accessible as {@link hooks | `this.hooks`} within
44
+ * your component class.
45
+ */
46
+ useHooks: () => object | void;
47
+ }
48
+ export declare const useLogic: UseLogic;
@@ -0,0 +1,113 @@
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
+ var _a;
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.useLogic = exports.ComponentLogic = void 0;
20
+ var react_1 = require("react");
21
+ var state_1 = require("../../base/state");
22
+ /**
23
+ * Base class for a class that holds methods intended for use in a function component,
24
+ * as well as a static method for initializing state.
25
+ *
26
+ * These methods will have access to the components state and props via
27
+ * `this.state` and `this.props` respectively.
28
+ *
29
+ * The special {@link Class['useHooks'] | useHooks} method allows you to consume
30
+ * React hooks within this class.
31
+ *
32
+ * Call the {@link useLogic} hook inside your function component to instantiate the class.
33
+ */
34
+ var ComponentLogic = /** @class */ (function () {
35
+ function ComponentLogic() {
36
+ /**
37
+ * Called before each instance of your component is mounted.
38
+ * It receives the initial `props` object and should return
39
+ * an object with the initial values for your component's state.
40
+ */
41
+ this.getInitialState = function (props) { return ({}); };
42
+ /**
43
+ * Call React hooks from here. If your component needs
44
+ * access to values return from the hooks you call,
45
+ * expose those values by returning an object with said values.
46
+ *
47
+ * The returned object will be accessible as {@link hooks | `this.hooks`} within
48
+ * your component class.
49
+ */
50
+ this.useHooks = function () { };
51
+ }
52
+ return ComponentLogic;
53
+ }());
54
+ exports.ComponentLogic = ComponentLogic;
55
+ ;
56
+ var useLogic = function () {
57
+ var _a;
58
+ var args = [];
59
+ for (var _i = 0; _i < arguments.length; _i++) {
60
+ args[_i] = arguments[_i];
61
+ }
62
+ var Logic = args[0], _b = args[1], props = _b === void 0 ? {} : _b;
63
+ var self = (0, react_1.useRef)((0, react_1.useMemo)(function () {
64
+ return new Logic();
65
+ }, [])).current;
66
+ /** A proxy variable to allow typechecking of the assignment to `self.props` despite the need for "readonly" error suppression. */
67
+ var _propsProxy_;
68
+ /** A proxy variable to allow typechecking of the assignment to `self.state` despite the need for "readonly" error suppression. */
69
+ var _stateProxy_;
70
+ /** A proxy variable to allow typechecking of the assignment to `self.hooks` despite the need for "readonly" error suppression. */
71
+ var _hooksProxy_;
72
+ // @ts-expect-error
73
+ self.props = (_propsProxy_ = props);
74
+ // @ts-expect-error
75
+ self.state = (_stateProxy_ = (0, state_1.useCleanState)(self.getInitialState, props));
76
+ // @ts-expect-error
77
+ self.hooks = (_hooksProxy_ = (_a = self.useHooks()) !== null && _a !== void 0 ? _a : {});
78
+ return self;
79
+ };
80
+ exports.useLogic = useLogic;
81
+ /**/
82
+ testing: {
83
+ var a = { b: '' };
84
+ var MyComponentLogic = /** @class */ (function (_super) {
85
+ __extends(MyComponentLogic, _super);
86
+ function MyComponentLogic() {
87
+ var _this = _super !== null && _super.apply(this, arguments) || this;
88
+ _this.getInitialState = function () { return ({ b: 7 }); };
89
+ _this.b = function () { return 8 + _this.state.b; };
90
+ _this.useHooks = function () { return ({ a: 'undefined' }); };
91
+ return _this;
92
+ }
93
+ return MyComponentLogic;
94
+ }(ComponentLogic));
95
+ ;
96
+ var self_1 = (0, exports.useLogic)(MyComponentLogic);
97
+ self_1.hooks;
98
+ self_1.useHooks();
99
+ var A = /** @class */ (function (_super) {
100
+ __extends(C, _super);
101
+ function C() {
102
+ var _this = _super !== null && _super.apply(this, arguments) || this;
103
+ _this.getInitialState = function () { return ({ a: 'l' }); };
104
+ _this.a = function () { return _this.state.a = ''; };
105
+ return _this;
106
+ }
107
+ return C;
108
+ }(ComponentLogic));
109
+ // const oa = {['a' as unknown as symbol]: 'boo'};
110
+ var oa = (_a = {}, _a['a'] = 'boo', _a);
111
+ (0, exports.useLogic)(A, oa);
112
+ }
113
+ /**/
@@ -0,0 +1,17 @@
1
+ import type { ComponentLogic } from '..';
2
+ /*************************************
3
+ * # Hooks *
4
+ **************************************/
5
+ /** */
6
+ type ULClassParam = typeof ComponentLogic<object>;
7
+ type ULProplessClassParam = typeof ComponentLogic<HardEmptyObject>;
8
+ export type UseLogic = {
9
+ <Class extends ULProplessClassParam>(Methods: Class): InstanceType<Class>;
10
+ <Class extends ULClassParam>(Methods: Class, props: InstanceType<Class>['props']): InstanceType<Class>;
11
+ };
12
+ export type ULParams = [
13
+ Class: typeof ComponentLogic,
14
+ props?: object
15
+ ];
16
+ export type ULReturn = ComponentLogic;
17
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,24 +1,16 @@
1
- /**
2
- * @file
3
- * This file is an "Ambient declarations file". The types defined here are available globally.
4
- * More info here: https://stackoverflow.com/a/73389225/985454
5
- *
6
- * Don't use `import` and `export` in this file directly! It breaks ambience.
7
- * To import external types in an ambient declarations file (this file) use the following:
8
- *
9
- * @example
10
- * declare type React = typeof import('react');
11
- *
12
- * To contribute ambient declarations from any file, even non-ambient ones, use this:
13
- *
14
- * @example
15
- * declare global {
16
- * interface Window {
17
- * ethereum: any
18
- * }
19
- * }
20
- **/
21
- /** */
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
+ }/**/
22
14
  declare global {
23
15
  type Optional<BaseType, AllowNull extends boolean = true> = (AllowNull extends true ? BaseType | undefined | null : BaseType | undefined);
24
16
  type Awaitable<Type> = Type | Promise<Type>;
@@ -37,11 +29,46 @@ declare global {
37
29
  * Pass a type argument to set whether `async` and/or `sync` functions are allowed.
38
30
  */
39
31
  interface IVoidFunction<AsyncType extends 'async' | 'sync' | 'both' = 'both'> {
40
- (): AsyncType extends 'async' ? Promise<void> : AsyncType extends 'sync' ? void : Promise<void> | void;
32
+ (): AsyncType extends 'async' ? Promise<void> : AsyncType extends 'sync' ? void : void | Promise<void>;
41
33
  }
42
34
  type AnyFunction = (...args: any) => any;
43
35
  type FunctionType = AnyFunction;
44
36
  type TFunction = AnyFunction;
37
+ /** @deprecated Use {@link NonNullish} */
38
+ type NotNullish = {};
39
+ type NonNullish = {};
40
+ type NonPrimitive = object;
41
+ /**
42
+ * Describes an object that has no keys,
43
+ * except for a secret unique symbol key,
44
+ * whose value type is the union `never | undefuned`.
45
+ *
46
+ * Having a single key allows the object to throw type errors
47
+ * of the form:
48
+ * ```
49
+ * Type `A` has no properties in common with `WeakEmptyObject`.
50
+ * ```
51
+ * This may provide a slightly stricter type checking than simply
52
+ * using the non-nullish (`{}`) or non-primitive (`object`)
53
+ * built-in types.
54
+ *
55
+ * Note: `WeakEmptyObject` is not assignable to `HardEmptyObject`
56
+ * because it has a key whose value type includes `undefined`,
57
+ * but `HardEmptyObject` keys can only have a type of `never`.
58
+ */
59
+ interface WeakEmptyObject {
60
+ [UniqueSecretSymbolKey]?: never;
61
+ }
62
+ /**
63
+ * Describes an object that can have any key, but all keys have
64
+ * a type of `never`. This effectively prevents any value
65
+ * from ever being stored on the object. The object is therefore
66
+ * guaranteed to always be empty.
67
+ */
68
+ interface HardEmptyObject {
69
+ [key: keyof any]: never;
70
+ }
71
+ type valueof<TObject> = TObject[keyof TObject];
45
72
  interface Window {
46
73
  }
47
74
  namespace JSX {
@@ -52,16 +79,5 @@ declare global {
52
79
  interface ProcessEnv {
53
80
  }
54
81
  }
55
- type __FromPrivateHelpers = typeof import('./globals.private');
56
- type TEmptyObject1 = {
57
- ''?: never;
58
- };
59
- type TEmptyObject2 = Record<symbol, never>;
60
- type EmptyObject = __FromPrivateHelpers['EmptyObject2'];
61
- type EmptyObject2 = __FromPrivateHelpers['EmptyObject2'];
62
- type EmptyObject3 = __FromPrivateHelpers['EmptyObject3'];
63
- type valueof<TObject> = TObject[keyof TObject];
64
- interface T extends __FromPrivateHelpers {
65
- }
66
82
  }
67
83
  export {};
package/build/globals.js CHANGED
@@ -1,22 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * @file
4
- * This file is an "Ambient declarations file". The types defined here are available globally.
5
- * More info here: https://stackoverflow.com/a/73389225/985454
6
- *
7
- * Don't use `import` and `export` in this file directly! It breaks ambience.
8
- * To import external types in an ambient declarations file (this file) use the following:
9
- *
10
- * @example
11
- * declare type React = typeof import('react');
12
- *
13
- * To contribute ambient declarations from any file, even non-ambient ones, use this:
14
- *
15
- * @example
16
- * declare global {
17
- * interface Window {
18
- * ethereum: any
19
- * }
20
- * }
21
- **/
22
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ /////////////
4
+ var UniqueSecretSymbolKey = Symbol('asdfghjkliuytrewqaxcvb,nb');
@@ -0,0 +1 @@
1
+ export * from './mount-state';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./mount-state"), exports);
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns a value that is false before the component has been mounted,
3
+ * then true during all subsequent rerenders.
4
+ */
5
+ export declare const useMountState: () => () => boolean;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useMountState = void 0;
4
+ var react_1 = require("react");
5
+ /**
6
+ * Returns a value that is false before the component has been mounted,
7
+ * then true during all subsequent rerenders.
8
+ */
9
+ var useMountState = function () {
10
+ /**
11
+ * This must not be a state value. It should not be the cause of a rerender.
12
+ * It merely provides information about the render count,
13
+ * without influencing that count itself.
14
+ * So `mounted` should never be set with `useState`.
15
+ */
16
+ var mounted = (0, react_1.useRef)(false);
17
+ (0, react_1.useEffect)(function () {
18
+ mounted.current = true;
19
+ return function () {
20
+ mounted.current = false;
21
+ };
22
+ }, []);
23
+ return function () { return mounted.current; };
24
+ };
25
+ exports.useMountState = useMountState;
package/build/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- export * from "./classy";
1
+ export * from './classy';
2
+ export * from './base';
3
+ export * from './helpers';
package/build/index.js CHANGED
@@ -15,24 +15,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./classy"), exports);
18
- // PS: Document component inheritance pattern with lifecycle callback arrays and namespaces.
19
- // Due to react's remounting behaviour, components must externally track when some logic has run, if it really really must only ever run once per mounted instance. Tricky to get right for components that may have multiple instance rendered simultaneously at different parts of a page.
20
- // useCleanState => useState, separate call for each key
21
- // useMergedState => useState, same call for all keys
22
- // useMethods => useCallback
23
- // useLogic => useCallback + all other hook calls.
24
- // useInstance => useLogic + lifecycle methods.
25
- /*
26
- - Write usage doc
27
- - Push to git and publish to site
28
- - Follow-up personal post on class component inheritance can be published on GH Pages from profile repo.
29
- - Publish to NPM
30
- - Finalize package and repo names, then post to Twitter.
31
- */
18
+ __exportStar(require("./base"), exports);
19
+ __exportStar(require("./helpers"), exports);
32
20
  /*
33
21
  withFetchApi(baseUrl); To mimic axios.get and axios.post type calls.
34
22
  @cleanweb/mem-store - Release global-store package here.
35
- Use mem-store to cache requests in createApi(); Use md5 hashed url as key.
23
+ Use mem-store to cache requests in withFetchApi(); Use md5 hashed url+body as key.
36
24
  @todo Add simple persistence layer with indexed db.
37
25
  @cleanweb/subscribable - To publish changes in the data to subscribers.
38
26
  @cleanweb/reactive-data - To combine all 4.
@@ -29,16 +29,19 @@
29
29
  "isolatedModules": true,
30
30
  "jsx": "react-jsx",
31
31
  "strictNullChecks": true,
32
+ "strictPropertyInitialization": true,
32
33
  "noImplicitAny": true,
33
34
  "noUncheckedIndexedAccess": true,
34
35
  "strictBindCallApply": true,
35
36
  "exactOptionalPropertyTypes": true,
36
37
  },
37
38
  "include": [
39
+ // "**/[!globals].ts",
38
40
  "**/*.ts",
39
41
  "**/*.tsx"
40
42
  ],
41
43
  "exclude": [
44
+ "**/globals.ts",
42
45
  "node_modules/**/**.*",
43
46
  "build/**/**.*",
44
47
  "mirror-pkg/**/**.*"