@cleanweb/react 1.1.1-beta.1 → 1.1.1-beta.11

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.
@@ -70,7 +70,9 @@ var MergedState = /** @class */ (function () {
70
70
  return MergedState;
71
71
  }());
72
72
  var useMergedState = function (initialState) {
73
- var cleanState = (0, react_1.useMemo)(function () { return new MergedState(initialState); }, []);
73
+ var cleanState = (0, react_1.useMemo)(function () {
74
+ return new MergedState(initialState);
75
+ }, []);
74
76
  MergedState.useRefresh.call(cleanState);
75
77
  return cleanState;
76
78
  };
@@ -1,8 +1,8 @@
1
- import type { TCleanState } from './state';
2
- export declare class ComponentMethods<TState extends object, TProps extends object> {
3
- state: TCleanState<TState>;
1
+ import type { TCleanState, TStateData } from './state';
2
+ export declare class ComponentMethods<TProps extends object, TState extends TStateData> {
4
3
  props: TProps;
4
+ state: TCleanState<TState>;
5
5
  }
6
- type UseMethods = <TMethods extends ComponentMethods<any, any>>(Methods: Constructor<TMethods>, state: TMethods['state'], props: TMethods['props']) => TMethods;
6
+ type UseMethods = <Class extends typeof ComponentMethods<object, object>>(Methods: Class & Constructor<InstanceType<Class>>, props: InstanceType<Class>['props'], state: InstanceType<Class>['state']) => InstanceType<Class>;
7
7
  export declare const useMethods: UseMethods;
8
8
  export {};
@@ -1,4 +1,55 @@
1
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
+ return new (P || (P = Promise))(function (resolve, reject) {
20
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
24
+ });
25
+ };
26
+ var __generator = (this && this.__generator) || function (thisArg, body) {
27
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
28
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
29
+ function verb(n) { return function (v) { return step([n, v]); }; }
30
+ function step(op) {
31
+ if (f) throw new TypeError("Generator is already executing.");
32
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
33
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
34
+ if (y = 0, t) op = [op[0] & 2, t.value];
35
+ switch (op[0]) {
36
+ case 0: case 1: t = op; break;
37
+ case 4: _.label++; return { value: op[1], done: false };
38
+ case 5: _.label++; y = op[1]; op = [0]; continue;
39
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
40
+ default:
41
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
42
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
43
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
44
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
45
+ if (t[2]) _.ops.pop();
46
+ _.trys.pop(); continue;
47
+ }
48
+ op = body.call(thisArg, _);
49
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
50
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
+ }
52
+ };
2
53
  Object.defineProperty(exports, "__esModule", { value: true });
3
54
  exports.useMethods = exports.ComponentMethods = void 0;
4
55
  var react_1 = require("react");
@@ -9,17 +60,40 @@ var ComponentMethods = /** @class */ (function () {
9
60
  }());
10
61
  exports.ComponentMethods = ComponentMethods;
11
62
  ;
12
- var useMethods = function (Methods, state, props) {
63
+ var useMethods = function (Methods, props, state) {
13
64
  // @todo Switch to useRef. Vite HMR seems to sometimes reinitialize useMemo calls after a hot update,
14
65
  // causing the instance to be unexpectedly recreated in the middle of the components lifecycle.
15
66
  // But useRef and useState values appear to always be preserved whenever this happens.
16
67
  // So those two are the only cross-render-persistence methods we can consider safe.
17
68
  var methods = (0, react_1.useRef)((0, react_1.useMemo)(function () {
18
- // See useLogic implementation for a discussion of this type assertion.
19
69
  return new Methods();
20
70
  }, [])).current;
21
- methods.state = state;
22
71
  methods.props = props;
72
+ methods.state = state;
23
73
  return methods;
24
74
  };
25
75
  exports.useMethods = useMethods;
76
+ testing: {
77
+ var a = function () { return __awaiter(void 0, void 0, void 0, function () {
78
+ var a, MyMethods, useCleanState, self;
79
+ return __generator(this, function (_a) {
80
+ switch (_a.label) {
81
+ case 0:
82
+ a = { b: '' };
83
+ MyMethods = /** @class */ (function (_super) {
84
+ __extends(MyMethods, _super);
85
+ function MyMethods() {
86
+ return _super !== null && _super.apply(this, arguments) || this;
87
+ }
88
+ return MyMethods;
89
+ }(ComponentMethods));
90
+ ;
91
+ return [4 /*yield*/, import('./state.js')];
92
+ case 1:
93
+ useCleanState = (_a.sent()).useCleanState;
94
+ self = (0, exports.useMethods)(MyMethods, {}, useCleanState({}));
95
+ return [2 /*return*/];
96
+ }
97
+ });
98
+ }); };
99
+ }
@@ -7,8 +7,8 @@ type PutState<TState extends object> = {
7
7
  [Key in keyof TState]: React.Dispatch<React.SetStateAction<TState[Key]>>;
8
8
  };
9
9
  declare class CleanStateBase<TState extends Record<string, any>> {
10
- reservedKeys: string[];
11
- valueKeys: string[];
10
+ readonly reservedKeys: string[];
11
+ readonly valueKeys: string[];
12
12
  private _values_;
13
13
  private _initialValues_;
14
14
  private _setters_;
@@ -16,14 +16,16 @@ declare class CleanStateBase<TState extends Record<string, any>> {
16
16
  static update: <TState_1 extends object>(this: CleanStateBase<TState_1>) => void;
17
17
  get put(): PutState<TState>;
18
18
  get initialState(): TState;
19
- putMany: (newValues: Partial<TState>) => void;
19
+ readonly putMany: (newValues: Partial<TState>) => void;
20
20
  }
21
- type TCleanStateInstance<TState extends object> = TState & CleanStateBase<TState>;
22
- export type TCleanState<TState extends object> = TCleanStateInstance<TState>;
23
- export type TState<YourCleanState extends CleanStateBase<{}>> = Omit<YourCleanState, keyof CleanStateBase<{}>>;
21
+ export type TStateData = object & {
22
+ [Key in keyof CleanStateBase<{}>]?: never;
23
+ };
24
+ export type TCleanState<TState extends TStateData> = (CleanStateBase<TState> & Omit<TState, keyof CleanStateBase<{}>>);
25
+ export type ExtractCleanStateData<YourCleanState extends CleanStateBase<{}>> = Omit<YourCleanState, keyof CleanStateBase<{}>>;
24
26
  type StateInitFunction = (...args: any[]) => object;
25
27
  type StateInit = object | StateInitFunction;
26
28
  type TInitialState<Initializer extends StateInit> = Initializer extends (...args: any[]) => (infer TState extends object) ? TState : Initializer;
27
- type TUseCleanState = <TInit extends StateInit>(_initialState: TInit, ...props: TInit extends (...args: infer TProps extends any[]) => (infer TState extends object) ? TProps : []) => TCleanStateInstance<TInitialState<TInit>>;
29
+ type TUseCleanState = <TInit extends StateInit>(_initialState: TInit, ...props: TInit extends (...args: infer TProps extends any[]) => (infer TState extends object) ? TProps : []) => TCleanState<TInitialState<TInit>>;
28
30
  export declare const useCleanState: TUseCleanState;
29
31
  export {};
@@ -122,17 +122,13 @@ var useCleanState = function (_initialState) {
122
122
  for (var _i = 1; _i < arguments.length; _i++) {
123
123
  props[_i - 1] = arguments[_i];
124
124
  }
125
- var mounted = (0, exports.useMountState)();
126
125
  var initialState = typeof _initialState === 'function'
127
126
  ? (0, react_1.useMemo)(function () { return _initialState.apply(void 0, props); }, [])
128
127
  : _initialState;
129
128
  ;
130
- var freshInstance = {};
131
- if (!mounted)
132
- freshInstance = new CleanState(initialState);
133
- if (!freshInstance.put)
134
- throw new Error('useCleanState failed to initialized a state instance.');
135
- var cleanState = (0, react_1.useRef)(freshInstance).current;
129
+ var cleanState = (0, react_1.useRef)((0, react_1.useMemo)(function () {
130
+ return new CleanState(initialState);
131
+ }, [])).current;
136
132
  CleanState.update.call(cleanState);
137
133
  return cleanState;
138
134
  };
@@ -1,11 +1,19 @@
1
1
  import type { VoidFunctionComponent } from 'react';
2
- import type { TComponentClass } from './logic';
2
+ import type { IComponentInstanceClass } from './instance';
3
+ import type { TStateData } from '../base';
3
4
  import { ComponentInstance } from './instance';
4
- type Extractor = <TComponent extends ClassComponent<object, object, object>>(this: TComponentClass<TComponent, typeof ClassComponent>, _Component?: TComponentClass<TComponent, typeof ClassComponent>) => VoidFunctionComponent<TComponent['props']>;
5
- export declare class ClassComponent<TState extends object = EmptyObject, TProps extends object = EmptyObject, THooks extends object = EmptyObject> extends ComponentInstance<TState, TProps, THooks> {
6
- Render: VoidFunctionComponent<{}>;
7
- static renderAs: 'component' | 'template';
8
- static FC: Extractor;
5
+ export declare const useRerender: () => () => void;
6
+ type ComponentClassParams = ConstructorParameters<typeof ClassComponent>;
7
+ type o = object;
8
+ export interface IComponentClass<Instance extends ClassComponent<o, o, o> = ClassComponent, Params extends ComponentClassParams = ComponentClassParams> extends IComponentInstanceClass<Instance, Params> {
9
+ }
10
+ type Extractor = <TComponent extends typeof ClassComponent<o, o, o>>(this: NonNullable<typeof _Component>, _Component?: TComponent & IComponentClass<InstanceType<TComponent>>) => VoidFunctionComponent<InstanceType<TComponent>['props']>;
11
+ type ReactTemplate = React.JSX.Element | null;
12
+ export declare class ClassComponent<TProps extends o = WeakEmptyObject, TState extends TStateData = WeakEmptyObject, THooks extends o = WeakEmptyObject> extends ComponentInstance<TProps, TState, THooks> {
13
+ Render?: VoidFunctionComponent<{}>;
14
+ template?: ReactTemplate | (() => ReactTemplate);
15
+ readonly forceUpdate: VoidFunction;
16
+ static readonly FC: Extractor;
9
17
  }
10
18
  interface HookWrapperProps<THookFunction extends AnyFunction> {
11
19
  hook: THookFunction;
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
15
15
  };
16
16
  })();
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.Use = exports.ClassComponent = void 0;
18
+ exports.Use = exports.ClassComponent = exports.useRerender = void 0;
19
19
  var jsx_runtime_1 = require("react/jsx-runtime");
20
20
  var react_1 = require("react");
21
21
  var instance_1 = require("./instance");
@@ -32,22 +32,41 @@ var setFunctionName = function (func, newName) {
32
32
  console.warn(error);
33
33
  }
34
34
  };
35
- // eslint-enable no-use-before-define
35
+ var useRerender = function () {
36
+ /*
37
+ * Skip the value, we don't need it.
38
+ * Grab just the setter function.
39
+ */
40
+ var _a = (0, react_1.useState)(Date.now()), _forceRerender = _a[1];
41
+ var rerender = function () { return _forceRerender(Date.now()); };
42
+ return rerender;
43
+ };
44
+ exports.useRerender = useRerender;
45
+ ;
36
46
  var ClassComponent = /** @class */ (function (_super) {
37
47
  __extends(ClassComponent, _super);
38
48
  function ClassComponent() {
39
49
  return _super !== null && _super.apply(this, arguments) || this;
40
50
  }
41
- ClassComponent.renderAs = 'component';
42
51
  ClassComponent.FC = function FC(_Component) {
43
52
  var Component = _Component !== null && _Component !== void 0 ? _Component : this;
44
53
  var isClassComponentType = Component.prototype instanceof ClassComponent;
45
54
  if (!Component.getInitialState || !isClassComponentType)
46
55
  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()`).');
47
- var Wrapper = function (props, context) {
48
- var Render = (0, instance_1.useInstance)(Component, props).Render;
56
+ var Wrapper = function (props) {
57
+ var instance = (0, instance_1.useInstance)(Component, props);
58
+ var Render = instance.Render, template = instance.template;
59
+ var _forceUpdate;
60
+ // @ts-expect-error (Cannot assign to 'forceUpdate' because it is a read-only property.ts(2540))
61
+ instance.forceUpdate = (_forceUpdate = (0, exports.useRerender)() // Moved this to separate line to allow TS errors. Use proxy local variable to regain some type checking for the assignment to `instance.forceUpdate`.
62
+ );
49
63
  // Add calling component name to Render function name in stack traces.
50
- (0, react_1.useMemo)(function () { return setFunctionName(Render, "".concat(Component.name, ".Render")); }, [Render]);
64
+ (0, react_1.useMemo)(function () {
65
+ if (typeof template === 'function')
66
+ setFunctionName(template, "".concat(Component.name, ".template"));
67
+ else if (typeof Render === 'function')
68
+ setFunctionName(Render, "".concat(Component.name, ".Render"));
69
+ }, [Render, template]);
51
70
  /**
52
71
  * Normally a component can update it's own state in the "before-render" stage to
53
72
  * skip DOM updates and trigger and immediate rerun of the rendering with the new state.
@@ -58,23 +77,37 @@ var ClassComponent = /** @class */ (function (_super) {
58
77
  * state in the "before-render" stage of `Render`, since it will be attempting to update it's parent's
59
78
  * state (i.e `Wrapper` component) rather than it's own state.
60
79
  *
61
- * Consider using this as a function call instead of JSX to avoid that. This way, we avoid
80
+ * Users should favor using the `template()` method instead. This way, we avoid
62
81
  * establishing a component boundary between `Wrapper` and `Render`.
63
82
  *
64
83
  * Although, since beforeRender() is called earlier from a hook, this is probably
65
84
  * a non-issue. It will only force users to move their logic into `beforeRender` instead
66
- * of doing it directly in `Render`. This might mean cleaner Render functions,
67
- * so there's probably no real value lost if we keep the component boundary.
85
+ * of doing it directly in `Render`. Even if `template` is being used, the `beforeRender` method
86
+ * is the preferred location for such logic to maintain a high level of separation of concerns,
87
+ * which is what this library exists to provide.
88
+ *
89
+ * So there's probably no real value lost with the component boundary. Users should just use
90
+ * `beforeRender` + `template`.
68
91
  **/
69
- if (Component.renderAs === 'template')
70
- return Render({}, context);
71
- // With the existence of useContext(),
72
- // what exactly does the context argument to FunctionComponent represent?
73
- // Do we need to find a way to pass that context value to <Render /> here?
74
- return (0, jsx_runtime_1.jsx)(Render, {});
92
+ switch (typeof template) {
93
+ case 'undefined':
94
+ if (typeof Render === 'function')
95
+ return (0, jsx_runtime_1.jsx)(Render, {});
96
+ else
97
+ throw new Error([
98
+ 'A ClassComponent must have either a `template` or a `Render` property. But neither was found.',
99
+ 'Add a `template` member to your class and assign a valid (JSX.Element | null) to it. (or a function that returns that).',
100
+ 'Alternatively, add a `Render` method and assign a FunctionComponent to it.',
101
+ '\n\n',
102
+ 'Expected `Render` to be a Function Component because `template` was `undefined`.',
103
+ "Instead got the following '".concat(typeof Render, "': $o"),
104
+ ].join(' '), Render);
105
+ case 'function': return template();
106
+ default: return template;
107
+ }
75
108
  };
76
109
  // Include calling component name in wrapper function name on stack traces.
77
- setFunctionName(Wrapper, "".concat(Component.name, " < Wrapper")); // ${Wrapper.name}
110
+ setFunctionName(Wrapper, "$".concat(Component.name, "$"));
78
111
  return Wrapper;
79
112
  };
80
113
  return ClassComponent;
@@ -89,3 +122,16 @@ var Use = function (params) {
89
122
  return null;
90
123
  };
91
124
  exports.Use = Use;
125
+ testing: {
126
+ var a = { b: '' };
127
+ var MyComponentLogic = /** @class */ (function (_super) {
128
+ __extends(MyComponentLogic, _super);
129
+ function MyComponentLogic() {
130
+ return _super !== null && _super.apply(this, arguments) || this;
131
+ }
132
+ MyComponentLogic.getInitialState = function () { return ({ a: '' }); };
133
+ return MyComponentLogic;
134
+ }(ClassComponent));
135
+ ;
136
+ var Template = MyComponentLogic.FC();
137
+ }
@@ -1,8 +1,10 @@
1
- import type { TComponentClass } from './logic';
2
- import { ComponentLogic } from './logic';
1
+ import { TStateData } from '../base/state';
2
+ import { ComponentLogic, IComponentLogicClass } from './logic';
3
3
  type AsyncAllowedEffectCallback = () => Awaitable<IVoidFunction>;
4
+ type UseMountCallbacks = <TInstance extends ComponentInstance<any, any, any>>(instance: TInstance) => void;
5
+ export declare const useMountCallbacks: UseMountCallbacks;
4
6
  export declare const noOp: () => void;
5
- export declare class ComponentInstance<TState extends object = EmptyObject, TProps extends object = EmptyObject, THooks extends object = EmptyObject> extends ComponentLogic<TState, TProps, THooks> {
7
+ export declare class ComponentInstance<TProps extends o = WeakEmptyObject, TState extends TStateData = WeakEmptyObject, THooks extends o = WeakEmptyObject> extends ComponentLogic<TProps, TState, THooks> {
6
8
  /**
7
9
  * Runs only _before_ first render, i.e before the component instance is mounted.
8
10
  * Useful for logic that is involved in determining what to render.
@@ -47,17 +49,13 @@ export declare class ComponentInstance<TState extends object = EmptyObject, TPro
47
49
  */
48
50
  cleanUp: IVoidFunction;
49
51
  }
50
- type UseInstance = <TClass extends ComponentInstance<object, object, object>>(Class: TComponentClass<TClass>, ...props: valueof<TClass['props']> extends never ? ([] | [EmptyObject] | [TClass['props']]) : [TClass['props']]) => TClass;
51
- /**
52
- * To ensure successful type checking, the second parameter must be written with spread syntax.
53
- * Likely because of the `exactOptionalPropertyTypes` config option turned on,
54
- * and `UseInstance` using an empty tuple in its rest parameter type, attempting to simply
55
- * retrieve the second argument directly causes an error when that argument is passed on to `useLogic`.
56
- * But directly working with the rest array bypasses the problem. Also note that the issue persists even when
57
- * the second param is given `{}` as a default follow to account for the empty tuple case. TypeScript
58
- * just wants us to use the rest parameter explicitly by force.
59
- */
52
+ type o = object;
53
+ type InstanceClassParams = ConstructorParameters<typeof ComponentInstance<o, o, o>>;
54
+ export interface IComponentInstanceClass<Instance extends ComponentInstance<o, o, o> = ComponentInstance, Params extends InstanceClassParams = InstanceClassParams> extends IComponentLogicClass<Instance, Params> {
55
+ }
56
+ type UseInstance = {
57
+ <Class extends typeof ComponentInstance<HardEmptyObject, o, o>>(Methods: Class & IComponentInstanceClass<InstanceType<Class>>, props?: HardEmptyObject): InstanceType<Class>;
58
+ <Class extends typeof ComponentInstance<o, o, o>>(Methods: Class & IComponentInstanceClass<InstanceType<Class>>, props: InstanceType<Class>['props']): InstanceType<Class>;
59
+ };
60
60
  export declare const useInstance: UseInstance;
61
- type UseMountCallbacks = <TInstance extends ComponentInstance<any, any, any>>(instance: TInstance) => void;
62
- export declare const useMountCallbacks: UseMountCallbacks;
63
61
  export {};
@@ -14,20 +14,36 @@ var __extends = (this && this.__extends) || (function () {
14
14
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
15
  };
16
16
  })();
17
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
19
- if (ar || !(i in from)) {
20
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
21
- ar[i] = from[i];
22
- }
23
- }
24
- return to.concat(ar || Array.prototype.slice.call(from));
25
- };
26
17
  Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.useMountCallbacks = exports.useInstance = exports.ComponentInstance = exports.noOp = void 0;
18
+ exports.useInstance = exports.ComponentInstance = exports.noOp = exports.useMountCallbacks = void 0;
28
19
  var react_1 = require("react");
29
20
  var state_1 = require("../base/state");
30
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;
31
47
  var noOp = function () { };
32
48
  exports.noOp = noOp;
33
49
  var ComponentInstance = /** @class */ (function (_super) {
@@ -83,7 +99,8 @@ var ComponentInstance = /** @class */ (function (_super) {
83
99
  }(logic_1.ComponentLogic));
84
100
  exports.ComponentInstance = ComponentInstance;
85
101
  ;
86
- /**
102
+ ;
103
+ /*
87
104
  * To ensure successful type checking, the second parameter must be written with spread syntax.
88
105
  * Likely because of the `exactOptionalPropertyTypes` config option turned on,
89
106
  * and `UseInstance` using an empty tuple in its rest parameter type, attempting to simply
@@ -92,14 +109,15 @@ exports.ComponentInstance = ComponentInstance;
92
109
  * the second param is given `{}` as a default follow to account for the empty tuple case. TypeScript
93
110
  * just wants us to use the rest parameter explicitly by force.
94
111
  */
95
- var useInstance = function (Component) {
112
+ var useInstance = function () {
96
113
  var _a;
97
114
  var args = [];
98
- for (var _i = 1; _i < arguments.length; _i++) {
99
- args[_i - 1] = arguments[_i];
115
+ for (var _i = 0; _i < arguments.length; _i++) {
116
+ args[_i] = arguments[_i];
100
117
  }
118
+ var Component = args[0], _b = args[1], props = _b === void 0 ? {} : _b;
101
119
  // useHooks.
102
- var instance = logic_1.useLogic.apply(void 0, __spreadArray([Component], args, false)); // Must spread rest parameter, rather than passing a single `props` argument directly.
120
+ var instance = (0, logic_1.useLogic)(Component, props); // Must spread rest parameter, rather than passing a single `props` argument directly.
103
121
  /**
104
122
  * Argument of type '
105
123
  * [
@@ -115,7 +133,6 @@ var useInstance = function (Component) {
115
133
  '
116
134
  */
117
135
  // beforeMount, onMount, cleanUp.
118
- // eslint-disable-next-line no-use-before-define
119
136
  (0, exports.useMountCallbacks)(instance);
120
137
  // beforeRender.
121
138
  (_a = instance.beforeRender) === null || _a === void 0 ? void 0 : _a.call(instance);
@@ -133,28 +150,12 @@ var useInstance = function (Component) {
133
150
  return instance;
134
151
  };
135
152
  exports.useInstance = useInstance;
136
- var useMountCallbacks = function (instance) {
137
- var _a;
138
- var mounted = (0, state_1.useMountState)();
139
- if (!mounted)
140
- (_a = instance.beforeMount) === null || _a === void 0 ? void 0 : _a.call(instance);
141
- (0, react_1.useEffect)(function () {
142
- var _a;
143
- var mountHandlerCleanUp = (_a = instance.onMount) === null || _a === void 0 ? void 0 : _a.call(instance);
144
- return function () {
145
- var doCleanUp = function (runMountCleaners) {
146
- var _a;
147
- runMountCleaners === null || runMountCleaners === void 0 ? void 0 : runMountCleaners();
148
- // onDismount? willUnmount?
149
- (_a = instance.cleanUp) === null || _a === void 0 ? void 0 : _a.call(instance);
150
- };
151
- if (typeof mountHandlerCleanUp === 'function') {
152
- doCleanUp(mountHandlerCleanUp);
153
- }
154
- else {
155
- mountHandlerCleanUp === null || mountHandlerCleanUp === void 0 ? void 0 : mountHandlerCleanUp.then(doCleanUp);
156
- }
157
- };
158
- }, []);
159
- };
160
- exports.useMountCallbacks = useMountCallbacks;
153
+ testing: {
154
+ var A = /** @class */ (function (_super) {
155
+ __extends(A, _super);
156
+ function A() {
157
+ return _super !== null && _super.apply(this, arguments) || this;
158
+ }
159
+ return A;
160
+ }(ComponentInstance));
161
+ }
@@ -1,22 +1,22 @@
1
- import type { TCleanState, TState } from '../base/state';
2
- export declare class ComponentLogic<TState extends object = EmptyObject, TProps extends object = EmptyObject, THooks extends object = EmptyObject> {
1
+ import type { TCleanState, ExtractCleanStateData, TStateData } from '../base/state';
2
+ export type HardEmpty = HardEmptyObject;
3
+ export type WeakEmpty = WeakEmptyObject;
4
+ type o = object;
5
+ export declare class ComponentLogic<TProps extends o = WeakEmpty, TState extends TStateData = WeakEmpty, // WeakEmpty,
6
+ THooks extends o = WeakEmpty> {
3
7
  state: TCleanState<TState>;
4
8
  props: TProps;
5
9
  hooks: THooks;
6
- static getInitialState: IComponentClass['getInitialState'];
7
- useHooks?: () => THooks;
10
+ static getInitialState: (p?: object) => object;
11
+ useHooks: THooks extends HardEmptyObject ? undefined | (() => HardEmptyObject | undefined) : () => THooks;
8
12
  }
9
- type CnstPrm = ConstructorParameters<typeof ComponentLogic>;
10
- export interface IComponentClass<Instance extends ComponentLogic = ComponentLogic> {
11
- new (...params: CnstPrm): Instance;
12
- getInitialState: (props?: Instance['props']) => TState<Instance['state']>;
13
+ type LogicClassParams = ConstructorParameters<typeof ComponentLogic>;
14
+ export interface IComponentLogicClass<Instance extends ComponentLogic<o, o, o> = ComponentLogic, Params extends LogicClassParams = LogicClassParams> extends Constructor<Instance, Params> {
15
+ getInitialState: (props?: Instance['props']) => ExtractCleanStateData<Instance['state']>;
13
16
  }
14
- export type ComponentClassStatics<Instance extends ComponentLogic<object, object, object>> = {
15
- getInitialState: (props?: Instance['props']) => TState<Instance['state']>;
17
+ type UseLogic = {
18
+ <Class extends typeof ComponentLogic<HardEmptyObject, o, o>>(Methods: Class & IComponentLogicClass<InstanceType<Class>>, props?: HardEmptyObject): InstanceType<Class>;
19
+ <Class extends typeof ComponentLogic<o, o, o>>(Methods: Class & IComponentLogicClass<InstanceType<Class>>, props: InstanceType<Class>['props']): InstanceType<Class>;
16
20
  };
17
- export type TComponentClass<Instance extends ComponentLogic<object, object, object>, Statics extends ComponentClassStatics<Instance> = ComponentClassStatics<Instance>, Params extends CnstPrm = CnstPrm> = Statics & Constructor<Instance, Params>;
18
- export interface IEmpty extends EmptyObject {
19
- }
20
- type UseLogic = <CLogic extends ComponentLogic<object, object, object>>(Methods: TComponentClass<CLogic>, ...props: valueof<CLogic['props']> extends never ? ([] | [EmptyObject] | [CLogic['props']]) : [CLogic['props']]) => CLogic;
21
- export declare const useLogic: UseLogic;
22
- export {};
21
+ declare const useLogic: UseLogic;
22
+ export { useLogic };
@@ -22,33 +22,25 @@ var state_1 = require("../base/state");
22
22
  var ComponentLogic = /** @class */ (function () {
23
23
  function ComponentLogic() {
24
24
  }
25
+ ComponentLogic.getInitialState = function (p) { return ({}); };
25
26
  return ComponentLogic;
26
27
  }());
27
28
  exports.ComponentLogic = ComponentLogic;
28
29
  ;
29
- testing: {
30
- var A = (_a = /** @class */ (function (_super) {
31
- __extends(C, _super);
32
- function C() {
33
- return _super !== null && _super.apply(this, arguments) || this;
34
- }
35
- return C;
36
- }(ComponentLogic)),
37
- _a.getInitialState = function () { return ({}); },
38
- _a);
39
- A.getInitialState();
40
- }
41
- ;
42
- var useLogic = function (Methods, props) {
43
- var _b;
44
- if (props === void 0) { props = {}; }
30
+ var useLogic = function () {
31
+ var _a, _b;
32
+ var args = [];
33
+ for (var _i = 0; _i < arguments.length; _i++) {
34
+ args[_i] = arguments[_i];
35
+ }
36
+ var Methods = args[0], _c = args[1], props = _c === void 0 ? {} : _c;
45
37
  var state = (0, state_1.useCleanState)(Methods.getInitialState, props);
46
38
  var methods = (0, react_1.useRef)((0, react_1.useMemo)(function () {
47
39
  return new Methods();
48
40
  }, [])).current;
49
41
  methods.state = state;
50
42
  methods.props = props;
51
- methods.hooks = ((_b = methods.useHooks) === null || _b === void 0 ? void 0 : _b.call(methods)) || {};
43
+ methods.hooks = (_b = (_a = methods.useHooks) === null || _a === void 0 ? void 0 : _a.call(methods)) !== null && _b !== void 0 ? _b : {};
52
44
  return methods;
53
45
  };
54
46
  exports.useLogic = useLogic;
@@ -59,9 +51,30 @@ testing: {
59
51
  function MyComponentLogic() {
60
52
  return _super !== null && _super.apply(this, arguments) || this;
61
53
  }
62
- MyComponentLogic.getInitialState = function () { return ({}); };
54
+ MyComponentLogic.getInitialState = function () { return ({ a: '' }); };
63
55
  return MyComponentLogic;
64
56
  }(ComponentLogic));
65
57
  ;
66
- (0, exports.useLogic)(MyComponentLogic);
58
+ MyComponentLogic.getInitialState;
59
+ // const self = useLogic(MyComponentLogic);
60
+ }
61
+ testing: {
62
+ var A = /** @class */ (function (_super) {
63
+ __extends(C, _super);
64
+ function C() {
65
+ return _super !== null && _super.apply(this, arguments) || this;
66
+ }
67
+ return C;
68
+ }(ComponentLogic));
69
+ A.getInitialState();
70
+ // const oa = {['a' as unknown as symbol]: 'boo'};
71
+ var oa = (_a = {}, _a['a'] = 'boo', _a);
72
+ // const self = useLogic(A, oa);
67
73
  }
74
+ // export type ComponentClassStatics<Instance extends ComponentLogic<object, object, object>> = {
75
+ // getInitialState: (props?: Instance['props']) => TState<Instance['state']>;
76
+ // }
77
+ // export type TComponentClass<
78
+ // Instance extends ComponentLogic<object, object, object>,
79
+ // Params extends CnstPrm = CnstPrm
80
+ // > = ComponentClassStatics<Instance> & Constructor<Instance, Params>;
@@ -1,24 +1,4 @@
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;
22
2
  declare global {
23
3
  type Optional<BaseType, AllowNull extends boolean = true> = (AllowNull extends true ? BaseType | undefined | null : BaseType | undefined);
24
4
  type Awaitable<Type> = Type | Promise<Type>;
@@ -42,6 +22,15 @@ declare global {
42
22
  type AnyFunction = (...args: any) => any;
43
23
  type FunctionType = AnyFunction;
44
24
  type TFunction = AnyFunction;
25
+ type NotNullish = {};
26
+ type NonPrimitive = object;
27
+ interface WeakEmptyObject {
28
+ [UniqueSecretSymbolKey]?: never;
29
+ }
30
+ interface HardEmptyObject {
31
+ [key: keyof any]: never;
32
+ }
33
+ type valueof<TObject> = TObject[keyof TObject];
45
34
  interface Window {
46
35
  }
47
36
  namespace JSX {
@@ -52,16 +41,5 @@ declare global {
52
41
  interface ProcessEnv {
53
42
  }
54
43
  }
55
- type __FromPrivateHelpers = typeof import('./globals.private');
56
- type TEmptyObject1 = {
57
- ''?: never;
58
- };
59
- type TEmptyObject2 = Record<symbol, never>;
60
- type EmptyObject = __FromPrivateHelpers['EmptyObject'];
61
- type EmptyObject2 = __FromPrivateHelpers['EmptyObject2'];
62
- type EmptyObject3 = __FromPrivateHelpers['EmptyObject3'];
63
- type valueof<TObject> = TObject[keyof TObject];
64
- interface T extends __FromPrivateHelpers {
65
- }
66
44
  }
67
45
  export {};
package/build/globals.js CHANGED
@@ -1,22 +1,14 @@
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');
5
+ testing: {
6
+ var mySymbol = Symbol('asdfgh');
7
+ var tt = {
8
+ // [mySymbol]: '' as never,
9
+ // [UniqueSecretSymbolKey]: '',
10
+ // '': '',
11
+ };
12
+ var TT = {};
13
+ TT = tt;
14
+ }
@@ -32,7 +32,7 @@
32
32
  "noImplicitAny": true,
33
33
  "noUncheckedIndexedAccess": true,
34
34
  "strictBindCallApply": true,
35
- // "exactOptionalPropertyTypes": true
35
+ "exactOptionalPropertyTypes": true,
36
36
  },
37
37
  "include": [
38
38
  "**/*.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleanweb/react",
3
- "version": "1.1.1-beta.1",
3
+ "version": "1.1.1-beta.11",
4
4
  "description": "A suite of helpers for writing cleaner React function components.",
5
5
  "engines": {
6
6
  "node": ">=18"
@@ -1,48 +0,0 @@
1
- /**
2
- * @file
3
- * This file is created specifically to augment the declarations in
4
- * [globals.d.ts]({@link ./globals.d.ts}).
5
- *
6
- * **You should not import this file directly.**
7
- */
8
- /** */
9
- declare const UniqueSecretSymbolKey: unique symbol;
10
- declare class CEmptyObject {
11
- [key: keyof any]: never;
12
- }
13
- declare class CEmptyObject2 {
14
- [UniqueSecretSymbolKey]?: never;
15
- }
16
- declare class CEmptyObject3 {
17
- /**
18
- * It appears keys of the base `symbol` type are excluded from
19
- * excess property checks. This is likely a bug in TypeScript.
20
- * Even the "has no properties in common" error disappears if the
21
- * value being placed into a variable has a key typed as `symbol`.
22
- * This only applies to the base `symbol` type. Specifc `'unique symbol'`
23
- * types are unaffected.
24
- *
25
- * @example
26
- * // Consider the following object:
27
- * const myUniqueSymbol = Symbol('lkjhgfc');
28
- * let myObj = { [myUniqueSymbol]?: 'a string value' };
29
- *
30
- * // We can attempt to reassign `myObj` with the expectation that TS will
31
- * // warn if any key other than `myUniqueSymbol` is used in the new object.
32
- * // But this breaks in one specific scenario.
33
- *
34
- * // No excess property check when this is used as a key.
35
- * // Error "no properties in common" also suppressed when this is used as a key.
36
- * const differentBasicSymbol = Symbol('qwertiop[') as symbol;
37
- * myObj = { [differentBasicSymbol]: 5 };
38
- *
39
- * // Errors emitted as expected when this is used as a key.
40
- * const differentUniqueSymbol = Symbol('zxcvbnm');
41
- * myObj = { [differentUniqueSymbol]: 5 };
42
- */
43
- [key: symbol]: never;
44
- }
45
- export declare const EmptyObject: CEmptyObject;
46
- export declare const EmptyObject2: CEmptyObject2;
47
- export declare const EmptyObject3: CEmptyObject3;
48
- export {};
@@ -1,40 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file
4
- * This file is created specifically to augment the declarations in
5
- * [globals.d.ts]({@link ./globals.d.ts}).
6
- *
7
- * **You should not import this file directly.**
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.EmptyObject3 = exports.EmptyObject2 = exports.EmptyObject = void 0;
11
- /** */
12
- var UniqueSecretSymbolKey = Symbol('asdfghjkliuytrewqaxcvb,nb');
13
- var CEmptyObject = /** @class */ (function () {
14
- function CEmptyObject() {
15
- }
16
- return CEmptyObject;
17
- }());
18
- var CEmptyObject2 = /** @class */ (function () {
19
- function CEmptyObject2() {
20
- }
21
- return CEmptyObject2;
22
- }());
23
- var CEmptyObject3 = /** @class */ (function () {
24
- function CEmptyObject3() {
25
- }
26
- return CEmptyObject3;
27
- }());
28
- exports.EmptyObject = new CEmptyObject();
29
- exports.EmptyObject2 = new CEmptyObject2();
30
- exports.EmptyObject3 = new CEmptyObject3();
31
- testing: {
32
- var mySymbol = Symbol('asdfgh');
33
- var tt = {
34
- // [mySymbol]: '' as never,
35
- // [UniqueSecretSymbolKey]: '',
36
- // '': '',
37
- };
38
- var TT = new CEmptyObject();
39
- TT = tt;
40
- }