@carbonorm/carbonreact 6.0.1 → 6.0.2

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/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/CarbonORM/CarbonReact"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "6.0.1",
8
+ "version": "6.0.2",
9
9
  "browser": "dist/index.umd.js",
10
10
  "type": "module",
11
11
  "main": "./dist/index.cjs",
@@ -8,6 +8,7 @@ import {initialRestfulObjectsState, iRestfulObjectArrayTypes} from "schema/C6";
8
8
  import CarbonWebSocket, {iCarbonWebSocketProps} from "components/WebSocket/CarbonWebSocket";
9
9
  import updateRestfulObjectArrays, {iUpdateRestfulObjectArrays} from "state/updateRestfulObjectArrays";
10
10
  import deleteRestfulObjectArrays, {iDeleteRestfulObjectArrays} from "state/deleteRestfulObjectArrays";
11
+ import { iStateAdapter } from "state/stateAdapter";
11
12
  import {BrowserRouter, HashRouter, MemoryRouter} from "react-router-dom";
12
13
 
13
14
  export type tStatefulApiData<T extends { [key: string]: any } = {}> = T[] | undefined | null;
@@ -56,7 +57,8 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
56
57
  instanceId?: string,
57
58
  persistentState?: boolean,
58
59
  routerType?: eRouterType,
59
- websocket?: Omit<iCarbonWebSocketProps<P, S>, "instance"> | false
60
+ websocket?: Omit<iCarbonWebSocketProps<P, S>, "instance"> | false,
61
+ stateAdapter?: iStateAdapter<S>
60
62
  } & P, S> {
61
63
 
62
64
  private static allInstances = new Map<string, CarbonReact<any, any>>();
@@ -114,6 +116,7 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
114
116
  websocket?: boolean | iCarbonWebSocketProps<P, S> | undefined;
115
117
  instanceId?: string; // Optional instanceId from props
116
118
  persistentState?: boolean; // Optional persistentState from props
119
+ stateAdapter?: iStateAdapter<S>;
117
120
  } & P) {
118
121
  super(props);
119
122
 
@@ -128,6 +131,7 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
128
131
  }
129
132
 
130
133
  this.target = new.target;
134
+ this.stateAdapter = props.stateAdapter;
131
135
  console.log('CarbonORM TSX CONSTRUCTOR');
132
136
 
133
137
  Object.assign(this.target, {
@@ -135,6 +139,8 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
135
139
  });
136
140
  }
137
141
 
142
+ public stateAdapter?: iStateAdapter<S>;
143
+
138
144
  private static generateIdentifier(instanceId?: string): string {
139
145
  const className = this.name;
140
146
  return instanceId ? `${className}-${instanceId}` : className;
package/src/index.ts CHANGED
@@ -44,6 +44,7 @@ export * from "./routing/GlobalHistory";
44
44
  export * from "./schema/C6";
45
45
  export { default as deleteRestfulObjectArrays } from "./state/deleteRestfulObjectArrays";
46
46
  export * from "./state/deleteRestfulObjectArrays";
47
+ export * from "./state/stateAdapter";
47
48
  export { default as updateRestfulObjectArrays } from "./state/updateRestfulObjectArrays";
48
49
  export * from "./state/updateRestfulObjectArrays";
49
50
  export { default as getStyles } from "./styles/getStyles";
@@ -1,5 +1,6 @@
1
1
  import CarbonReact, { iCarbonReactState, tStatefulApiData } from "core/CarbonReact";
2
2
  import { KeysMatching } from "types/KeysMatching";
3
+ import { iStateAdapter } from "./stateAdapter";
3
4
 
4
5
  export interface iDeleteRestfulObjectArrays<
5
6
  ObjectType extends {
@@ -12,7 +13,8 @@ export interface iDeleteRestfulObjectArrays<
12
13
  dataOrCallback: ObjectType[] | ((state: Readonly<S>, props: Readonly<P>) => ObjectType[] | null),
13
14
  stateKey: KeysMatching<S, tStatefulApiData<ObjectType>>,
14
15
  uniqueObjectId: keyof ObjectType | (keyof ObjectType)[],
15
- callback?: () => void
16
+ callback?: () => void,
17
+ stateAdapter?: iStateAdapter<S>
16
18
  }
17
19
 
18
20
  export default function deleteRestfulObjectArrays<
@@ -26,12 +28,14 @@ export default function deleteRestfulObjectArrays<
26
28
  dataOrCallback,
27
29
  stateKey,
28
30
  uniqueObjectId,
29
- callback
31
+ callback,
32
+ stateAdapter
30
33
  }: iDeleteRestfulObjectArrays<ObjectType, S, P>): void {
31
34
 
32
35
  const uniqueObjectIds = Array.isArray(uniqueObjectId) ? uniqueObjectId : [uniqueObjectId];
36
+ const resolvedStateAdapter = stateAdapter ?? instance.stateAdapter;
33
37
 
34
- instance.setState((
38
+ const computeNextState = (
35
39
  previousBootstrapState: Readonly<S & iCarbonReactState>,
36
40
  props: Readonly<P>
37
41
  ): Pick<S & iCarbonReactState, keyof S> | null => {
@@ -72,5 +76,17 @@ export default function deleteRestfulObjectArrays<
72
76
  [stateKey]: updatedStateProperty
73
77
  } as Pick<S & iCarbonReactState, keyof S>;
74
78
 
75
- }, callback);
79
+ };
80
+
81
+ if (resolvedStateAdapter) {
82
+ const previousBootstrapState = resolvedStateAdapter.getState();
83
+ const nextState = computeNextState(previousBootstrapState, instance.props as Readonly<P>);
84
+ if (nextState !== null) {
85
+ resolvedStateAdapter.setState(nextState as Partial<S>);
86
+ callback?.();
87
+ }
88
+ return;
89
+ }
90
+
91
+ instance.setState(computeNextState, callback);
76
92
  }
@@ -0,0 +1,37 @@
1
+ export interface iStateAdapter<S> {
2
+ getState(): S;
3
+ setState(partial: Partial<S>): void;
4
+ }
5
+
6
+ export class InMemoryStateAdapter<S extends Record<string, any>> implements iStateAdapter<S> {
7
+ private state: S;
8
+
9
+ constructor(initialState: S) {
10
+ this.state = initialState;
11
+ }
12
+
13
+ getState(): S {
14
+ return this.state;
15
+ }
16
+
17
+ setState(partial: Partial<S>): void {
18
+ this.state = { ...this.state, ...partial };
19
+ }
20
+
21
+ snapshot(): S {
22
+ return this.state;
23
+ }
24
+
25
+ hydrate(snapshot: S): void {
26
+ this.state = snapshot;
27
+ }
28
+ }
29
+
30
+ export const serializeStateSnapshot = <S>(state: S): string => JSON.stringify(state);
31
+
32
+ export const deserializeStateSnapshot = <S>(serialized: string): S => JSON.parse(serialized) as S;
33
+
34
+ export const getStateSnapshot = <S>(adapter: iStateAdapter<S>): S => adapter.getState();
35
+
36
+ export const createInMemoryStateAdapter = <S extends Record<string, any>>(initialState: S) =>
37
+ new InMemoryStateAdapter(initialState);
@@ -1,6 +1,7 @@
1
1
  import CarbonReact, { iCarbonReactState, tStatefulApiData } from "core/CarbonReact";
2
2
  import { KeysMatching } from "types/KeysMatching";
3
3
  import { SubsetMatching } from "types/SubsetMatching";
4
+ import { iStateAdapter } from "./stateAdapter";
4
5
 
5
6
  export enum eUpdateInsertMethod {
6
7
  REPLACE,
@@ -21,6 +22,7 @@ export interface iUpdateRestfulObjectArrays<
21
22
  uniqueObjectId: keyof ObjectType | (keyof ObjectType)[];
22
23
  insertUpdateOrder?: eUpdateInsertMethod;
23
24
  callback?: () => void;
25
+ stateAdapter?: iStateAdapter<S>;
24
26
  }
25
27
 
26
28
  /**
@@ -45,16 +47,18 @@ export default function updateRestfulObjectArrays<
45
47
  uniqueObjectId,
46
48
  insertUpdateOrder = eUpdateInsertMethod.LAST,
47
49
  callback,
50
+ stateAdapter,
48
51
  }: iUpdateRestfulObjectArrays<ObjectType, S, P>): void {
49
52
 
50
53
  const uniqueObjectIds = Array.isArray(uniqueObjectId) ? uniqueObjectId : [uniqueObjectId];
54
+ const resolvedStateAdapter = stateAdapter ?? instance.stateAdapter;
51
55
 
52
56
  type ValidObject = SubsetMatching<S & iCarbonReactState, tStatefulApiData<ObjectType>>;
53
57
 
54
- instance.setState((
55
- previousBootstrapState: Readonly<S>,
56
- props: Readonly<P>
57
- ): Pick<S & iCarbonReactState, keyof S> | null => {
58
+ const computeNextState = (
59
+ previousBootstrapState: Readonly<S>,
60
+ props: Readonly<P>
61
+ ): Pick<S & iCarbonReactState, keyof S> | null => {
58
62
 
59
63
  let newOrReplacementData: ObjectType[] | null = [];
60
64
 
@@ -125,7 +129,17 @@ export default function updateRestfulObjectArrays<
125
129
  }
126
130
 
127
131
  return newState as Pick<S & iCarbonReactState, keyof S>;
128
- },
129
- callback
130
- );
132
+ };
133
+
134
+ if (resolvedStateAdapter) {
135
+ const previousBootstrapState = resolvedStateAdapter.getState();
136
+ const nextState = computeNextState(previousBootstrapState, instance.props as Readonly<P>);
137
+ if (nextState !== null) {
138
+ resolvedStateAdapter.setState(nextState as Partial<S>);
139
+ callback?.();
140
+ }
141
+ return;
142
+ }
143
+
144
+ instance.setState(computeNextState, callback);
131
145
  }