@nu-art/app-state 0.400.7
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/frontend/_ats/ATS_AppState/ATS_AppState.d.ts +2 -0
- package/frontend/_ats/ATS_AppState/ATS_AppState.js +23 -0
- package/frontend/_modules/ModuleFE_AppState.d.ts +20 -0
- package/frontend/_modules/ModuleFE_AppState.js +98 -0
- package/frontend/_modules/consts.d.ts +1 -0
- package/frontend/_modules/consts.js +1 -0
- package/package.json +65 -0
- package/shared/index.d.ts +1 -0
- package/shared/index.js +1 -0
- package/shared/types.d.ts +4 -0
- package/shared/types.js +1 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, ComponentSync, LL_V_L, TS_Input, TS_PropRenderer } from '@nu-art/thunderstorm-frontend/index';
|
|
3
|
+
import { thunderstormCapabilitiesGroup } from '@nu-art/thunderstorm-frontend/consts';
|
|
4
|
+
import { PageStateManager } from '../../_modules/ModuleFE_AppState.js';
|
|
5
|
+
import { md5 } from '@nu-art/ts-common';
|
|
6
|
+
const manager = new PageStateManager(`/app-tools/${md5('App State')}`);
|
|
7
|
+
class ATS_AppState_Class extends ComponentSync {
|
|
8
|
+
deriveStateFromProps(p, state) {
|
|
9
|
+
state.value_Input ??= manager.value.get('value_Input');
|
|
10
|
+
return state;
|
|
11
|
+
}
|
|
12
|
+
render() {
|
|
13
|
+
return _jsxs(LL_V_L, { children: [_jsx(TS_PropRenderer.Horizontal, { label: 'Input', children: _jsx(TS_Input, { type: 'text', value: this.state.value_Input, onChange: val => {
|
|
14
|
+
this.setState({ value_Input: val }, () => manager.value.set('value_Input', val));
|
|
15
|
+
} }) }), _jsx(Button, { variant: 'primary', onClick: () => manager.getExportURL(), children: "Export State" })] });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export const ATS_AppState = {
|
|
19
|
+
key: 'ats-app-state',
|
|
20
|
+
name: 'App State',
|
|
21
|
+
renderer: ATS_AppState_Class,
|
|
22
|
+
group: thunderstormCapabilitiesGroup,
|
|
23
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Logger, TS_Object } from '@nu-art/ts-common';
|
|
2
|
+
import { ThunderDispatcher } from '@nu-art/thunderstorm-frontend/index';
|
|
3
|
+
export interface OnPageStateUpdated {
|
|
4
|
+
__onPageStateUpdated: (manager: PageStateManager<any>) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare const dispatch_OnPageStateUpdated: ThunderDispatcher<OnPageStateUpdated, "__onPageStateUpdated", [manager: PageStateManager<any>], void>;
|
|
7
|
+
export declare class PageStateManager<PageState extends TS_Object> extends Logger {
|
|
8
|
+
readonly route: string;
|
|
9
|
+
constructor(route: string);
|
|
10
|
+
value: {
|
|
11
|
+
get: <K extends keyof PageState>(stateKey: K) => PageState[K];
|
|
12
|
+
set: <K extends keyof PageState>(stateKey: K, value: PageState[K]) => void;
|
|
13
|
+
};
|
|
14
|
+
state: {
|
|
15
|
+
get: () => PageState;
|
|
16
|
+
set: (state: Partial<PageState>) => void;
|
|
17
|
+
};
|
|
18
|
+
getDispatchListenerCB: (cb: VoidFunction) => (manager: PageStateManager<any>) => void;
|
|
19
|
+
getExportURL: () => void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { _keys, BadImplementationException, cloneObj, composeUrl, deepClone, exists, Logger, mergeObject, Module } from '@nu-art/ts-common';
|
|
2
|
+
import { ModuleFE_BrowserHistory, ModuleFE_Thunderstorm, StorageKey, ThunderDispatcher } from '@nu-art/thunderstorm-frontend/index';
|
|
3
|
+
import { convertBase64ToObject, convertObjectToBase64 } from '@nu-art/thunderstorm-shared/base64-tools';
|
|
4
|
+
import { URLParam_AppState } from './consts.js';
|
|
5
|
+
export const dispatch_OnPageStateUpdated = new ThunderDispatcher('__onPageStateUpdated');
|
|
6
|
+
class ModuleFE_AppState_Class extends Module {
|
|
7
|
+
pathRegistry;
|
|
8
|
+
appState;
|
|
9
|
+
localStorage;
|
|
10
|
+
sessionStorage;
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
this.localStorage = new StorageKey('app-state', true);
|
|
14
|
+
this.sessionStorage = new StorageKey('app-state', false);
|
|
15
|
+
this.pathRegistry = {};
|
|
16
|
+
this.appState = this.sessionStorage.get(() => this.localStorage.get({}));
|
|
17
|
+
this.deriveStateFromURLParam();
|
|
18
|
+
}
|
|
19
|
+
registerManager = (manager) => {
|
|
20
|
+
if (exists(this.pathRegistry[manager.route]))
|
|
21
|
+
throw new BadImplementationException(`A manager is already registered for route: ${manager.route}`);
|
|
22
|
+
this.pathRegistry[manager.route] = manager;
|
|
23
|
+
};
|
|
24
|
+
// ######################### State Interaction #########################
|
|
25
|
+
setPageState = (manager, state) => {
|
|
26
|
+
this.appState[manager.route] = state;
|
|
27
|
+
this.sessionStorage.set(this.appState);
|
|
28
|
+
this.localStorage.set(this.appState);
|
|
29
|
+
};
|
|
30
|
+
getPageState = (manager) => this.appState[manager.route] ?? {};
|
|
31
|
+
// ######################### Import / Export #########################
|
|
32
|
+
deriveStateFromURLParam = () => {
|
|
33
|
+
const encoded = ModuleFE_BrowserHistory.getQueryParameter(URLParam_AppState);
|
|
34
|
+
if (!exists(encoded))
|
|
35
|
+
return;
|
|
36
|
+
const decoded = this.decodeState(encoded);
|
|
37
|
+
_keys(decoded).forEach(key => {
|
|
38
|
+
this.appState[key] = mergeObject(this.appState[key], decoded[key]);
|
|
39
|
+
});
|
|
40
|
+
ModuleFE_BrowserHistory.removeQueryParam(URLParam_AppState);
|
|
41
|
+
};
|
|
42
|
+
getExportStateForManager = (manager) => {
|
|
43
|
+
const pageState = this.getPageState(manager);
|
|
44
|
+
const appState = { [manager.route]: pageState };
|
|
45
|
+
const encoded = this.encodeState(appState);
|
|
46
|
+
const baseUrl = window.location.origin + manager.route;
|
|
47
|
+
return composeUrl(baseUrl, { [URLParam_AppState]: encoded });
|
|
48
|
+
};
|
|
49
|
+
encodeState = (decoded) => {
|
|
50
|
+
return convertObjectToBase64(decoded);
|
|
51
|
+
};
|
|
52
|
+
decodeState = (encoded) => {
|
|
53
|
+
return convertBase64ToObject(encoded);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const ModuleFE_AppState = new ModuleFE_AppState_Class();
|
|
57
|
+
export class PageStateManager extends Logger {
|
|
58
|
+
route;
|
|
59
|
+
constructor(route) {
|
|
60
|
+
super();
|
|
61
|
+
this.route = route;
|
|
62
|
+
ModuleFE_AppState.registerManager(this);
|
|
63
|
+
}
|
|
64
|
+
// ######################### State Interaction #########################
|
|
65
|
+
value = {
|
|
66
|
+
get: (stateKey) => {
|
|
67
|
+
const pageState = this.state.get();
|
|
68
|
+
return pageState[stateKey];
|
|
69
|
+
},
|
|
70
|
+
set: (stateKey, value) => {
|
|
71
|
+
const _value = deepClone(value);
|
|
72
|
+
const nextPageState = this.state.get();
|
|
73
|
+
nextPageState[stateKey] = _value;
|
|
74
|
+
ModuleFE_AppState.setPageState(this, nextPageState);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
state = {
|
|
78
|
+
get: () => {
|
|
79
|
+
return ModuleFE_AppState.getPageState(this);
|
|
80
|
+
},
|
|
81
|
+
set: (state) => {
|
|
82
|
+
const prevPageState = this.state.get();
|
|
83
|
+
const nextPageState = mergeObject(prevPageState, cloneObj(state));
|
|
84
|
+
ModuleFE_AppState.setPageState(this, nextPageState);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
// ######################### Utils #########################
|
|
88
|
+
getDispatchListenerCB = (cb) => {
|
|
89
|
+
return (manager) => {
|
|
90
|
+
if (manager === this)
|
|
91
|
+
cb();
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
getExportURL = () => {
|
|
95
|
+
const url = ModuleFE_AppState.getExportStateForManager(this);
|
|
96
|
+
ModuleFE_Thunderstorm.copyToClipboard(url, 'Export URL copied to clipboard');
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const URLParam_AppState = "app-state";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const URLParam_AppState = 'app-state';
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nu-art/app-state",
|
|
3
|
+
"version": "0.400.7",
|
|
4
|
+
"description": "App State",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"TacB0sS",
|
|
7
|
+
"express",
|
|
8
|
+
"infra",
|
|
9
|
+
"nu-art",
|
|
10
|
+
"thunderstorm",
|
|
11
|
+
"typescript"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/nu-art-js/thunderstorm",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/nu-art-js/thunderstorm/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+ssh://git@github.com:nu-art-js/thunderstorm.git"
|
|
20
|
+
},
|
|
21
|
+
"license": "Apache-2.0",
|
|
22
|
+
"author": "TacB0sS",
|
|
23
|
+
"main": "index.js",
|
|
24
|
+
"types": "index.d.ts",
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc"
|
|
27
|
+
},
|
|
28
|
+
"contributors": [
|
|
29
|
+
{
|
|
30
|
+
"name": "TacB0sS"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "Cipher",
|
|
34
|
+
"url": "https://www.linkedin.com/in/itay-leybovich-470b87229/"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"directory": "dist",
|
|
39
|
+
"linkDirectory": true
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@nu-art/ts-common": "0.400.7",
|
|
43
|
+
"@nu-art/ts-styles": "0.400.7",
|
|
44
|
+
"@nu-art/thunderstorm-shared": "0.400.7",
|
|
45
|
+
"@nu-art/thunderstorm-frontend": "0.400.7",
|
|
46
|
+
"react": "^18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/react": "^18.0.0"
|
|
50
|
+
},
|
|
51
|
+
"unitConfig": {
|
|
52
|
+
"type": "typescript-lib"
|
|
53
|
+
},
|
|
54
|
+
"type": "module",
|
|
55
|
+
"exports": {
|
|
56
|
+
".": {
|
|
57
|
+
"types": "./index.d.ts",
|
|
58
|
+
"import": "./index.js"
|
|
59
|
+
},
|
|
60
|
+
"./*": {
|
|
61
|
+
"types": "./*.d.ts",
|
|
62
|
+
"import": "./*.js"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types.js';
|
package/shared/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types.js';
|
package/shared/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|