septor-store-react 0.0.2 → 0.0.3
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 +4 -1
- package/src/index.ts +0 -7
- package/src/setUp/GlobalScripts/AbortHandler.ts +0 -13
- package/src/setUp/GlobalScripts/Axios.ts +0 -67
- package/src/setUp/GlobalScripts/useFetch.ts +0 -65
- package/src/setUp/pomStore.jsx +0 -170
- package/tsconfig.json +0 -13
- package/vite.config.ts +0 -23
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "septor-store-react",
|
|
3
3
|
"description": "PomStore is a lightweight, flexible global state & API store for React. It simplifies data fetching, caching, and shared state management—without Redux or heavy boilerplate. Built for real-world React apps that need fast data access, request de-duplication, and cache-first loading. PomStore is built on top of Zustand, a lightweight state management library for React.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
9
12
|
"scripts": {
|
|
10
13
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
11
14
|
"build": "vite build",
|
package/src/index.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import customAxios from "./Axios";
|
|
2
|
-
|
|
3
|
-
const AbortHandler = {
|
|
4
|
-
abortController: new AbortController(),
|
|
5
|
-
|
|
6
|
-
abortHttpRequests() {
|
|
7
|
-
this.abortController.abort();
|
|
8
|
-
this.abortController = new AbortController();
|
|
9
|
-
customAxios.defaults.signal = this.abortController.signal;
|
|
10
|
-
},
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default AbortHandler;
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
|
-
import { getBearerToken } from "./useFetch";
|
|
3
|
-
import AbortHandler from "./AbortHandler";
|
|
4
|
-
|
|
5
|
-
let baseURL =
|
|
6
|
-
typeof import.meta !== "undefined"
|
|
7
|
-
? (import.meta.env.VITE_BACKEND_URL ?? "")
|
|
8
|
-
: "";
|
|
9
|
-
export const setBaseURL = (c: { backendURL?: string }) => {
|
|
10
|
-
if (c.backendURL) {
|
|
11
|
-
baseURL = c.backendURL;
|
|
12
|
-
customAxios.defaults.baseURL = baseURL;
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
const customAxios = axios.create({
|
|
16
|
-
baseURL: baseURL,
|
|
17
|
-
signal: AbortHandler.abortController.signal, // Signal that is assiciated with any request to be made with this axios instance
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// Request Interceptor
|
|
21
|
-
const requestHandler = (request: any) => {
|
|
22
|
-
const tokenData = getBearerToken();
|
|
23
|
-
const token = tokenData?.token ?? null; // Always retrieve the latest token
|
|
24
|
-
const expiresIn = tokenData?.expiresIn ?? null;
|
|
25
|
-
|
|
26
|
-
if (expiresIn) {
|
|
27
|
-
const timestamp = tokenData?.timestamp ?? null;
|
|
28
|
-
const now = Date.now();
|
|
29
|
-
if (expiresIn && now - timestamp > expiresIn * 1000) {
|
|
30
|
-
console.warn("Token has expired.");
|
|
31
|
-
localStorage.removeItem("logginToken");
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
request.headers = { ...request.headers };
|
|
36
|
-
if (token) {
|
|
37
|
-
request.headers.Authorization = `Bearer ${token}`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Handle FormData explicitly if needed
|
|
41
|
-
if (request.data instanceof FormData) {
|
|
42
|
-
const formData = request.data;
|
|
43
|
-
request.data = formData;
|
|
44
|
-
} else if (request.data) {
|
|
45
|
-
request.data = { ...(request.data ?? {}) };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return request;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// Response Interceptor
|
|
52
|
-
customAxios.interceptors.response.use(
|
|
53
|
-
(response) => response, // Resolve response as is
|
|
54
|
-
(error) => {
|
|
55
|
-
console.log("Error.....", error);
|
|
56
|
-
if (error.response?.status === 401) {
|
|
57
|
-
}
|
|
58
|
-
return Promise.reject(error); // Reject the error for further handling
|
|
59
|
-
},
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
// Attach Request Interceptor
|
|
63
|
-
customAxios.interceptors.request.use(requestHandler, (error) =>
|
|
64
|
-
Promise.reject(error),
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
export default customAxios;
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import customAxios from "./Axios";
|
|
2
|
-
|
|
3
|
-
const useFetch = async ({ url, method, data }:any) => {
|
|
4
|
-
let _data = data ?? {};
|
|
5
|
-
try {
|
|
6
|
-
let response=null;
|
|
7
|
-
const uniformMethod = method.toLowerCase();
|
|
8
|
-
if (uniformMethod === 'get') {
|
|
9
|
-
const params = generateParams(_data ?? {});
|
|
10
|
-
response = await customAxios.get(`${url}${params}`);
|
|
11
|
-
} else
|
|
12
|
-
response = await customAxios.post(url, _data);
|
|
13
|
-
|
|
14
|
-
return response?.data ?? { Empty: 'Empty' };
|
|
15
|
-
} catch (err) {
|
|
16
|
-
console.error(err);
|
|
17
|
-
return { success: false, error: err };
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const generateParams = (params:any={}) => {
|
|
22
|
-
try {
|
|
23
|
-
|
|
24
|
-
let data = "?";
|
|
25
|
-
for (let key in params) {
|
|
26
|
-
if (Object.hasOwnProperty.call(params, key)) {
|
|
27
|
-
if (params[key]) {
|
|
28
|
-
if (Array.isArray(params[key])) {
|
|
29
|
-
const elements = params[key] ;
|
|
30
|
-
for (const ele of elements) {
|
|
31
|
-
data += `${key}[]=${ele}&`;
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
data += `${key}=${params[key]}&`;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return data.slice(0, -1);
|
|
40
|
-
} catch (error) {
|
|
41
|
-
console.error(error);
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
function setBearerToken(name = { token: null }) {
|
|
47
|
-
if (typeof name !== "object" || name === null || Array.isArray(name))
|
|
48
|
-
throw new TypeError("setBearerToken expects an object {token} with a 'token' property.");
|
|
49
|
-
|
|
50
|
-
const tokenObj = { token: null, ...name,timestamp: Date.now() };
|
|
51
|
-
localStorage.setItem("logginToken", JSON.stringify(tokenObj));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function getBearerToken() {
|
|
55
|
-
const token = localStorage.getItem('logginToken');
|
|
56
|
-
try {
|
|
57
|
-
return token ? JSON.parse(token) : null;
|
|
58
|
-
} catch (e) {
|
|
59
|
-
console.error('Invalid token format in localStorage:', e);
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
export { useFetch, generateParams, setBearerToken, getBearerToken };
|
package/src/setUp/pomStore.jsx
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { create } from "zustand";
|
|
2
|
-
import axios from "./GlobalScripts/Axios";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const ZpStore = create((set, get) => ({
|
|
6
|
-
loading: false,
|
|
7
|
-
stateValue: {},
|
|
8
|
-
checkQueriesInQue: {},
|
|
9
|
-
isThereAnyDataChangeInAform: false,
|
|
10
|
-
|
|
11
|
-
setStateValue: (key, value) =>
|
|
12
|
-
set((state) => ({
|
|
13
|
-
stateValue: { ...state.stateValue, [key]: value },
|
|
14
|
-
})),
|
|
15
|
-
|
|
16
|
-
getStateItem: (key) => get().stateValue[key],
|
|
17
|
-
// getStateItem: (key) => get().stateValue[key],
|
|
18
|
-
sleep: (ms) => new Promise((res) => setTimeout(res, ms)),
|
|
19
|
-
|
|
20
|
-
validateLength: (obj) => {
|
|
21
|
-
if (Array.isArray(obj)) return obj.length;
|
|
22
|
-
if (typeof obj === "object") return Object.keys(obj).length;
|
|
23
|
-
return 0;
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
callApiData: async (
|
|
27
|
-
stateKey,
|
|
28
|
-
callApiKey,
|
|
29
|
-
req,
|
|
30
|
-
paginated = false,
|
|
31
|
-
useSession = false,
|
|
32
|
-
) => {
|
|
33
|
-
const { checkQueriesInQue } = get();
|
|
34
|
-
if (get().getStateItem("checkQueriesInQue")?.[callApiKey]) {
|
|
35
|
-
console.warn(
|
|
36
|
-
`************************************* dont call this api again ${req["url"]} 🛩️ *************************************`,
|
|
37
|
-
req,
|
|
38
|
-
);
|
|
39
|
-
return; //get().getStateItem(stateKey)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
get().setStateValue("loading", true);
|
|
43
|
-
get().setStateValue("checkQueriesInQue", {
|
|
44
|
-
...checkQueriesInQue,
|
|
45
|
-
[callApiKey]: callApiKey,
|
|
46
|
-
});
|
|
47
|
-
const res = await axios(req);
|
|
48
|
-
if (res?.status == 200) {
|
|
49
|
-
set({ [stateKey]: res?.data });
|
|
50
|
-
get().setStateValue(stateKey, res?.data);
|
|
51
|
-
// console.log( ({ [stateKey]: res.data }))
|
|
52
|
-
if (useSession) {
|
|
53
|
-
sessionStorage.setItem(stateKey, JSON.stringify(res?.data));
|
|
54
|
-
}
|
|
55
|
-
} else {
|
|
56
|
-
console.error(res);
|
|
57
|
-
}
|
|
58
|
-
get().cleareQueApi(callApiKey);
|
|
59
|
-
set({ loading: false });
|
|
60
|
-
|
|
61
|
-
return res;
|
|
62
|
-
},
|
|
63
|
-
cleareQueApi: (callApiKey) => {
|
|
64
|
-
const currentQueue = get().stateValue.checkQueriesInQue || {};
|
|
65
|
-
const newQueue = { ...currentQueue };
|
|
66
|
-
delete newQueue[callApiKey];
|
|
67
|
-
get().setStateValue("checkQueriesInQue", newQueue);
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
complatedTheCall: async (
|
|
71
|
-
state,
|
|
72
|
-
stateKey,
|
|
73
|
-
key,
|
|
74
|
-
req,
|
|
75
|
-
paginated,
|
|
76
|
-
useSession,
|
|
77
|
-
onData,
|
|
78
|
-
) => {
|
|
79
|
-
const res = await state.callApiData(
|
|
80
|
-
stateKey,
|
|
81
|
-
key,
|
|
82
|
-
req,
|
|
83
|
-
paginated,
|
|
84
|
-
useSession,
|
|
85
|
-
);
|
|
86
|
-
if (res?.status == 200) {
|
|
87
|
-
onData && onData(res?.data);
|
|
88
|
-
|
|
89
|
-
return res?.data;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
onData && onData([]);
|
|
93
|
-
return res?.data;
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
stateGeneratorApi: async (
|
|
97
|
-
{ reload, stateKey, req, time = 0, paginated = false, mStore = {} },
|
|
98
|
-
onData,
|
|
99
|
-
) => {
|
|
100
|
-
set({ [stateKey]: [] });
|
|
101
|
-
const key = JSON.stringify(req); // put it out to be seen in error section
|
|
102
|
-
try {
|
|
103
|
-
const useSession = mStore?.mUse;
|
|
104
|
-
const state = get();
|
|
105
|
-
set({ loading: true });
|
|
106
|
-
|
|
107
|
-
if (useSession) {
|
|
108
|
-
const data = JSON.parse(sessionStorage.getItem(stateKey) || "{}");
|
|
109
|
-
|
|
110
|
-
if (state.validateLength(data)) {
|
|
111
|
-
|
|
112
|
-
if (onData) {
|
|
113
|
-
onData(data);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
set({ [stateKey]: data });
|
|
117
|
-
get().setStateValue(stateKey, data);
|
|
118
|
-
console.log(data)
|
|
119
|
-
if (!reload) return data;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Use existing if not reloading
|
|
124
|
-
const existingData = state?.[stateKey]??get().getStateItem(stateKey);
|
|
125
|
-
// console.log({existingData});
|
|
126
|
-
if (state.validateLength(existingData)) {
|
|
127
|
-
if (onData) onData(existingData);
|
|
128
|
-
// set({ loading: false })
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Fetch new data
|
|
132
|
-
if (reload && time > 0) {
|
|
133
|
-
setTimeout(() => {
|
|
134
|
-
get().complatedTheCall(
|
|
135
|
-
state,
|
|
136
|
-
stateKey,
|
|
137
|
-
key,
|
|
138
|
-
req,
|
|
139
|
-
paginated,
|
|
140
|
-
useSession,
|
|
141
|
-
onData,
|
|
142
|
-
);
|
|
143
|
-
}, time * 1000);
|
|
144
|
-
}
|
|
145
|
-
return await get().complatedTheCall(
|
|
146
|
-
state,
|
|
147
|
-
stateKey,
|
|
148
|
-
key,
|
|
149
|
-
req,
|
|
150
|
-
paginated,
|
|
151
|
-
useSession,
|
|
152
|
-
onData,
|
|
153
|
-
);
|
|
154
|
-
} catch (error) {
|
|
155
|
-
get().cleareQueApi(key);
|
|
156
|
-
// get().cleareQueApi(stateKey)
|
|
157
|
-
if (onData) onData([]);
|
|
158
|
-
console.error(error);
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
}));
|
|
162
|
-
|
|
163
|
-
// console.log(import.meta.env.VITE_BACKEND_URL);
|
|
164
|
-
|
|
165
|
-
;
|
|
166
|
-
export const Store = ZpStore
|
|
167
|
-
|
|
168
|
-
export default function usePomZStore() {
|
|
169
|
-
return Store();
|
|
170
|
-
}
|
package/tsconfig.json
DELETED
package/vite.config.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vite";
|
|
2
|
-
import react from "@vitejs/plugin-react";
|
|
3
|
-
import path from "path";
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
plugins: [react()],
|
|
7
|
-
build: {
|
|
8
|
-
lib: {
|
|
9
|
-
entry: path.resolve(__dirname, "src/index.ts"),
|
|
10
|
-
name: "septor-store-react",
|
|
11
|
-
fileName: "index",
|
|
12
|
-
},
|
|
13
|
-
rollupOptions: {
|
|
14
|
-
external: ["react", "react-dom"],
|
|
15
|
-
output: {
|
|
16
|
-
globals: {
|
|
17
|
-
react: "React",
|
|
18
|
-
"react-dom": "ReactDOM",
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
});
|