@carbonorm/carbonreact 4.0.11 → 4.0.12
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/dist/CarbonReact.d.ts +10 -4
- package/dist/index.cjs.js +18 -27
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +18 -27
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/CarbonReact.tsx +41 -68
package/package.json
CHANGED
package/src/CarbonReact.tsx
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {clearCache} from "@carbonorm/carbonnode";
|
|
1
|
+
import { clearCache } from "@carbonorm/carbonnode";
|
|
2
2
|
import changed from "hoc/changed";
|
|
3
|
-
import {GlobalHistory} from "hoc/GlobalHistory";
|
|
3
|
+
import { GlobalHistory } from "hoc/GlobalHistory";
|
|
4
4
|
import hexToRgb from "hoc/hexToRgb";
|
|
5
|
-
import {Component, Context, createContext, ReactElement, ReactNode} from 'react';
|
|
6
|
-
import {ToastContainer} from 'react-toastify';
|
|
5
|
+
import { Component, Context, createContext, ReactElement, ReactNode } from 'react';
|
|
6
|
+
import { ToastContainer } from 'react-toastify';
|
|
7
7
|
import 'react-toastify/dist/ReactToastify.min.css';
|
|
8
8
|
import BackendThrowable from 'components/Errors/BackendThrowable';
|
|
9
9
|
import Nest from 'components/Nest/Nest';
|
|
10
|
-
import {initialRestfulObjectsState, iRestfulObjectArrayTypes} from "variables/C6";
|
|
11
|
-
import CarbonWebSocket, {iCarbonWebSocketProps} from "./components/WebSocket/CarbonWebSocket";
|
|
12
|
-
import updateRestfulObjectArrays, {iUpdateRestfulObjectArrays} from "./hoc/updateRestfulObjectArrays";
|
|
13
|
-
import deleteRestfulObjectArrays, {iDeleteRestfulObjectArrays} from "./hoc/deleteRestfulObjectArrays";
|
|
10
|
+
import { initialRestfulObjectsState, iRestfulObjectArrayTypes } from "variables/C6";
|
|
11
|
+
import CarbonWebSocket, { iCarbonWebSocketProps } from "./components/WebSocket/CarbonWebSocket";
|
|
12
|
+
import updateRestfulObjectArrays, { iUpdateRestfulObjectArrays } from "./hoc/updateRestfulObjectArrays";
|
|
13
|
+
import deleteRestfulObjectArrays, { iDeleteRestfulObjectArrays } from "./hoc/deleteRestfulObjectArrays";
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
export type tStatefulApiData<T extends {
|
|
@@ -46,40 +46,32 @@ export function isJsonString(str: string) {
|
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
48
|
return true;
|
|
49
|
-
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactState> extends Component<{
|
|
53
52
|
children?: ReactNode | ReactNode[],
|
|
54
53
|
instanceId?: string,
|
|
55
54
|
websocket?: Omit<iCarbonWebSocketProps<P, S>, "instance"> | false
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactState> extends Component<iCarbonReactProps<P, S> & P, S> {
|
|
55
|
+
} & P, S> {
|
|
59
56
|
|
|
60
57
|
private static persistentStateMap = new Map<string, { [key: string]: any; }>();
|
|
58
|
+
private static activeInstances = new Map<string, CarbonReact<any, any>>();
|
|
61
59
|
|
|
62
|
-
// Context is for functional components to access the state of this class efficiently
|
|
63
60
|
context: Context<S & iCarbonReactState> = createContext(this.state);
|
|
64
|
-
|
|
65
61
|
protected target: typeof CarbonReact;
|
|
66
62
|
|
|
67
|
-
// @link https://stackoverflow.com/questions/55029032/what-is-typescripts-thistype-used-for
|
|
68
63
|
protected static _instance: ThisType<CarbonReact<any, any>>;
|
|
69
64
|
|
|
70
65
|
static getInstance<T extends CarbonReact<any, any>>(): T {
|
|
71
66
|
return this._instance as T;
|
|
72
67
|
}
|
|
73
|
-
|
|
74
68
|
static get instance() {
|
|
75
69
|
return this.getInstance();
|
|
76
70
|
}
|
|
77
|
-
|
|
78
71
|
static set instance(instance: CarbonReact<any, any>) {
|
|
79
72
|
this._instance = instance;
|
|
80
73
|
}
|
|
81
74
|
|
|
82
|
-
// these are public but the class is abstract
|
|
83
75
|
public updateRestfulObjectArrays = <ObjectType extends { [key: string]: any; } = {}>
|
|
84
76
|
(rest: Omit<iUpdateRestfulObjectArrays<ObjectType, S, P>, "instance">) => updateRestfulObjectArrays<ObjectType, S, P>({
|
|
85
77
|
instance: this,
|
|
@@ -94,76 +86,57 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
|
|
|
94
86
|
|
|
95
87
|
static lastLocation = window.location.pathname;
|
|
96
88
|
|
|
97
|
-
// @link https://github.com/welldone-software/why-did-you-render
|
|
98
|
-
// noinspection JSUnusedGlobalSymbols
|
|
99
89
|
static whyDidYouRender = true;
|
|
100
90
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
91
|
+
protected constructor(props: {
|
|
92
|
+
children?: ReactNode | ReactNode[];
|
|
93
|
+
shouldStatePersist?: boolean | undefined;
|
|
94
|
+
websocket?: boolean | iCarbonWebSocketProps<P, S> | undefined;
|
|
95
|
+
instanceId?: string; // Optional instanceId from props
|
|
96
|
+
} & P) {
|
|
104
97
|
super(props);
|
|
105
98
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// todo - instanceId being unique should solve this, but.... how
|
|
109
|
-
// This is a singleton pattern, we can only have one instance of this class
|
|
110
|
-
throw new Error(`${new.target.name} instance already exists! CarbonReact extended classes can only be referenced once in DOM`);
|
|
99
|
+
const target = new.target as typeof CarbonReact;
|
|
100
|
+
const identifier = props.instanceId || target.name;
|
|
111
101
|
|
|
102
|
+
if (CarbonReact.activeInstances.has(identifier)) {
|
|
103
|
+
throw new Error(`Instance with ID ${identifier} already exists! CarbonReact extended classes can only be referenced once in DOM with the same identifier.`);
|
|
112
104
|
}
|
|
113
105
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.target = new.target;
|
|
106
|
+
CarbonReact.activeInstances.set(identifier, this);
|
|
117
107
|
|
|
108
|
+
this.target = target;
|
|
118
109
|
console.log('CarbonORM TSX CONSTRUCTOR');
|
|
119
110
|
|
|
120
|
-
|
|
121
|
-
// new.target is a meta-property introduced in ES6 that references the constructor that was directly invoked with the new keyword.
|
|
122
|
-
Object.assign(new.target, {
|
|
111
|
+
Object.assign(target, {
|
|
123
112
|
_instance: this
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
if (this.props.instanceId && CarbonReact.persistentStateMap.has(this.props.instanceId)) {
|
|
127
|
-
|
|
128
|
-
this.state = CarbonReact.persistentStateMap.get(this.props.instanceId) as S & iCarbonReactState;
|
|
113
|
+
});
|
|
129
114
|
|
|
115
|
+
if (CarbonReact.persistentStateMap.has(identifier)) {
|
|
116
|
+
this.state = CarbonReact.persistentStateMap.get(identifier) as S & iCarbonReactState;
|
|
130
117
|
} else {
|
|
131
|
-
|
|
132
|
-
// This should only ever be done here, when the full state is being trashed.
|
|
133
|
-
// todo - does this suck in context of multiple instances?
|
|
134
118
|
clearCache({
|
|
135
119
|
ignoreWarning: true
|
|
136
120
|
});
|
|
137
|
-
|
|
138
121
|
this.state = initialCarbonReactState as unknown as S & iCarbonReactState;
|
|
139
|
-
|
|
140
122
|
}
|
|
141
123
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
* Class based components are far easier to manage state in local storage and pass state down to children.
|
|
145
|
-
* Children, if not faced with a local storage or other complexity should be a functional component. Functional
|
|
146
|
-
* components' tend to be shorter syntactically and bonus points if it's stateless.
|
|
147
|
-
**/
|
|
148
|
-
|
|
124
|
+
// Save the initial state to the persistent state map with the identifier
|
|
125
|
+
CarbonReact.persistentStateMap.set(identifier, this.state);
|
|
149
126
|
}
|
|
150
127
|
|
|
151
|
-
|
|
152
128
|
shouldComponentUpdate(
|
|
153
129
|
nextProps: Readonly<P>,
|
|
154
130
|
nextState: Readonly<S>,
|
|
155
131
|
_nextContext: any): boolean {
|
|
156
132
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
133
|
+
const identifier = this.props.instanceId || (this.constructor as typeof CarbonReact).name;
|
|
134
|
+
CarbonReact.persistentStateMap.set(identifier, nextState);
|
|
160
135
|
|
|
161
136
|
changed(this.constructor.name + ' (C6Api)', 'props', this.props, nextProps);
|
|
162
|
-
|
|
163
137
|
changed(this.constructor.name + ' (C6Api)', 'state', this.state, nextState);
|
|
164
138
|
|
|
165
|
-
return true
|
|
166
|
-
|
|
139
|
+
return true;
|
|
167
140
|
}
|
|
168
141
|
|
|
169
142
|
componentDidUpdate(_prevProps: Readonly<P>, _prevState: Readonly<S>, _snapshot?: any) {
|
|
@@ -178,39 +151,39 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
|
|
|
178
151
|
}
|
|
179
152
|
|
|
180
153
|
render(): ReactElement {
|
|
181
|
-
|
|
182
154
|
console.log('CarbonORM TSX RENDER');
|
|
183
155
|
|
|
184
156
|
const colorHex = '#' + Math.random().toString(16).slice(-6);
|
|
185
157
|
|
|
186
158
|
console.log('%c color (' + colorHex + ')', 'color: ' + colorHex);
|
|
187
159
|
|
|
188
|
-
const nest = <Nest position={'fixed'} backgroundColor={''} color={hexToRgb(colorHex)} count={100}/>;
|
|
160
|
+
const nest = <Nest position={'fixed'} backgroundColor={''} color={hexToRgb(colorHex)} count={100} />;
|
|
189
161
|
|
|
190
162
|
if (this.state.backendThrowable.length > 0) {
|
|
191
|
-
|
|
192
163
|
return <>
|
|
193
164
|
{nest}
|
|
194
|
-
<BackendThrowable instance={this}/>
|
|
165
|
+
<BackendThrowable instance={this} />
|
|
195
166
|
</>;
|
|
196
|
-
|
|
197
167
|
}
|
|
198
168
|
|
|
199
169
|
const Context = this.context.Provider;
|
|
200
170
|
|
|
201
171
|
return <>
|
|
202
|
-
<GlobalHistory/>
|
|
172
|
+
<GlobalHistory />
|
|
203
173
|
{this.props.websocket &&
|
|
204
174
|
<CarbonWebSocket<P, S> {...(false !== this.props.websocket ? this.props.websocket : {})}
|
|
205
|
-
instance={this}/>}
|
|
175
|
+
instance={this} />}
|
|
206
176
|
<Context value={this.state}>
|
|
207
177
|
{this.props.children}
|
|
208
178
|
</Context>
|
|
209
|
-
<ToastContainer/>
|
|
179
|
+
<ToastContainer />
|
|
210
180
|
</>;
|
|
211
|
-
|
|
212
181
|
}
|
|
213
182
|
|
|
183
|
+
componentWillUnmount() {
|
|
184
|
+
const identifier = this.props.instanceId || (this.constructor as typeof CarbonReact).name;
|
|
185
|
+
CarbonReact.activeInstances.delete(identifier);
|
|
186
|
+
}
|
|
214
187
|
}
|
|
215
188
|
|
|
216
189
|
export default CarbonReact;
|