Compare commits
3 Commits
dev-global
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
812a5f4626 | ||
|
|
ac6dcbffec | ||
|
|
7257a86376 |
@@ -1,5 +1,11 @@
|
|||||||
# @warkypublic/zustandsyncstore
|
# @warkypublic/zustandsyncstore
|
||||||
|
|
||||||
|
## 0.0.31
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- ac6dcbf: Error Boundry
|
||||||
|
|
||||||
## 0.0.30
|
## 0.0.30
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
35
package.json
35
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@warkypublic/oranguru",
|
"name": "@warkypublic/oranguru",
|
||||||
"author": "Warky Devs",
|
"author": "Warky Devs",
|
||||||
"version": "0.0.30",
|
"version": "0.0.31",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"types": "./dist/lib.d.ts",
|
"types": "./dist/lib.d.ts",
|
||||||
"main": "./dist/lib.cjs.js",
|
"main": "./dist/lib.cjs.js",
|
||||||
@@ -42,40 +42,43 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.29.8",
|
"@changesets/cli": "^2.29.8",
|
||||||
"@eslint/js": "^9.39.2",
|
"@eslint/js": "^9.39.2",
|
||||||
"@storybook/react-vite": "^10.2.1",
|
"@microsoft/api-extractor": "^7.56.0",
|
||||||
|
"@storybook/react-vite": "^10.2.3",
|
||||||
"@testing-library/jest-dom": "^6.9.1",
|
"@testing-library/jest-dom": "^6.9.1",
|
||||||
"@testing-library/react": "^16.3.2",
|
"@testing-library/react": "^16.3.2",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/node": "^25.1.0",
|
"@types/jsdom": "~27.0.0",
|
||||||
|
"@types/node": "^25.2.0",
|
||||||
"@types/react": "^19.2.10",
|
"@types/react": "^19.2.10",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"@types/use-sync-external-store": "~1.5.0",
|
||||||
"@typescript-eslint/parser": "^8.54.0",
|
"@typescript-eslint/parser": "^8.54.0",
|
||||||
"@vitejs/plugin-react-swc": "^4.2.2",
|
"@vitejs/plugin-react-swc": "^4.2.3",
|
||||||
"eslint": "^9.38.0",
|
"eslint": "^9.39.2",
|
||||||
"eslint-config-mantine": "^4.0.3",
|
"eslint-config-mantine": "^4.0.3",
|
||||||
"eslint-plugin-perfectionist": "^5.4.0",
|
"eslint-plugin-perfectionist": "^5.4.0",
|
||||||
"eslint-plugin-react": "^7.37.5",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"eslint-plugin-react-refresh": "^0.4.24",
|
"eslint-plugin-react-refresh": "^0.5.0",
|
||||||
"eslint-plugin-storybook": "^9.1.15",
|
"eslint-plugin-storybook": "^10.2.3",
|
||||||
"global": "^4.4.0",
|
"global": "^4.4.0",
|
||||||
"globals": "^17.2.0",
|
"globals": "^17.3.0",
|
||||||
"jiti": "^2.6.1",
|
"jiti": "^2.6.1",
|
||||||
"jsdom": "^27.4.0",
|
"jsdom": "^28.0.0",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"postcss-preset-mantine": "^1.18.0",
|
"postcss-preset-mantine": "^1.18.0",
|
||||||
"postcss-simple-vars": "^7.0.1",
|
"postcss-simple-vars": "^7.0.1",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.8.1",
|
||||||
"prettier-eslint": "^16.4.2",
|
"prettier-eslint": "^16.4.2",
|
||||||
"react": "^19.2.4",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.4",
|
"react-dom": "^19.2.4",
|
||||||
"storybook": "^9.1.15",
|
"storybook": "^10.2.3",
|
||||||
"typescript": "~5.9.3",
|
"typescript": "~5.9.3",
|
||||||
"typescript-eslint": "^8.46.2",
|
"typescript-eslint": "^8.54.0",
|
||||||
"vite": "^7.1.12",
|
"vite": "^7.3.1",
|
||||||
"vite-plugin-dts": "^4.5.4",
|
"vite-plugin-dts": "^4.5.4",
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^6.0.5",
|
||||||
"vitest": "^4.0.3"
|
"vitest": "^4.0.18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@glideapps/glide-data-grid": "^6.0.3",
|
"@glideapps/glide-data-grid": "^6.0.3",
|
||||||
@@ -87,11 +90,11 @@
|
|||||||
"@tanstack/react-query": "^5.90.5",
|
"@tanstack/react-query": "^5.90.5",
|
||||||
"@warkypublic/artemis-kit": "^1.0.10",
|
"@warkypublic/artemis-kit": "^1.0.10",
|
||||||
"@warkypublic/zustandsyncstore": "^0.0.4",
|
"@warkypublic/zustandsyncstore": "^0.0.4",
|
||||||
|
"idb-keyval": "^6.2.2",
|
||||||
"immer": "^10.1.3",
|
"immer": "^10.1.3",
|
||||||
"react": ">= 19.0.0",
|
"react": ">= 19.0.0",
|
||||||
"react-dom": ">= 19.0.0",
|
"react-dom": ">= 19.0.0",
|
||||||
"react-hook-form": "^7.71.0",
|
"react-hook-form": "^7.71.0",
|
||||||
"idb-keyval": "^6.2.2",
|
|
||||||
"use-sync-external-store": ">= 1.4.0",
|
"use-sync-external-store": ">= 1.4.0",
|
||||||
"zustand": ">= 5.0.0"
|
"zustand": ">= 5.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
1407
pnpm-lock.yaml
generated
1407
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,237 +0,0 @@
|
|||||||
import type { StoreApi } from 'zustand';
|
|
||||||
|
|
||||||
import { produce } from 'immer';
|
|
||||||
import { shallow } from 'zustand/shallow';
|
|
||||||
import { useStoreWithEqualityFn } from 'zustand/traditional';
|
|
||||||
import { createStore } from 'zustand/vanilla';
|
|
||||||
|
|
||||||
import type { ExtractState, GlobalState, GlobalStateStoreState } from './GlobalStateStore.types';
|
|
||||||
|
|
||||||
import { loadStorage, saveStorage } from './GlobalStateStore.utils';
|
|
||||||
|
|
||||||
const emptyStore: GlobalState = {
|
|
||||||
connected: true, //Only invalidate when a connection cannot be made
|
|
||||||
controls: {},
|
|
||||||
environment: 'production',
|
|
||||||
loading: false,
|
|
||||||
meta: {},
|
|
||||||
program: {
|
|
||||||
name: '',
|
|
||||||
slug: '',
|
|
||||||
},
|
|
||||||
|
|
||||||
user: {
|
|
||||||
access_control: false,
|
|
||||||
avatar_docid: 0,
|
|
||||||
id: 0,
|
|
||||||
login: '',
|
|
||||||
name: 'Guest',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
//We use vanilla store because we must be able to get the API key and token outside a react render loop
|
|
||||||
//The storage is custom because zustand's vanilla stores persist API crashes.
|
|
||||||
//Also not using the other store because it's using outdated methods and give that warning
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A zustand store function for managing program data and session information.
|
|
||||||
*
|
|
||||||
* @returns A zustand store state object.
|
|
||||||
*/
|
|
||||||
const GlobalStateStore = createStore<GlobalStateStoreState>((set, get) => ({
|
|
||||||
...emptyStore,
|
|
||||||
fetchData: async (url?: string) => {
|
|
||||||
const setFetched = async (
|
|
||||||
fn: (partial: GlobalState | Partial<GlobalState>) => Partial<GlobalStateStoreState>
|
|
||||||
) => {
|
|
||||||
const state = fn(get());
|
|
||||||
set((cur) => {
|
|
||||||
return { ...cur, ...state };
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
set((s) => ({
|
|
||||||
...s,
|
|
||||||
loading: true,
|
|
||||||
session: { ...s.session, apiURL: url ?? s.session.apiURL },
|
|
||||||
}));
|
|
||||||
|
|
||||||
const result = get().onFetchSession?.(get());
|
|
||||||
|
|
||||||
await setFetched((s) => ({
|
|
||||||
...s,
|
|
||||||
...result,
|
|
||||||
connected: true,
|
|
||||||
loading: false,
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
}));
|
|
||||||
} catch (e) {
|
|
||||||
await setFetched((s) => ({
|
|
||||||
...s,
|
|
||||||
connected: false,
|
|
||||||
error: `Load Exception: ${String(e)}`,
|
|
||||||
loading: false,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
login: async (sessionData?: string) => {
|
|
||||||
const state = get();
|
|
||||||
const newstate = {
|
|
||||||
...state,
|
|
||||||
session: { ...state.session, authtoken: sessionData ?? '' },
|
|
||||||
user: { ...state.user },
|
|
||||||
};
|
|
||||||
|
|
||||||
set((cur) => {
|
|
||||||
return { ...cur, ...newstate };
|
|
||||||
});
|
|
||||||
await get().fetchData();
|
|
||||||
},
|
|
||||||
logout: async () => {
|
|
||||||
const newstate = { ...get(), ...emptyStore };
|
|
||||||
|
|
||||||
set((state) => {
|
|
||||||
return { ...state, ...newstate };
|
|
||||||
});
|
|
||||||
await get().fetchData();
|
|
||||||
},
|
|
||||||
|
|
||||||
setAuthToken: (token: string) =>
|
|
||||||
set(
|
|
||||||
produce((state) => {
|
|
||||||
state.session.authtoken = token;
|
|
||||||
})
|
|
||||||
),
|
|
||||||
setIsSecurity: (issecurity: boolean) =>
|
|
||||||
set(
|
|
||||||
produce((state) => {
|
|
||||||
state.session.jsonvalue.issecurity = issecurity;
|
|
||||||
})
|
|
||||||
),
|
|
||||||
setState: (key, value) =>
|
|
||||||
set(
|
|
||||||
produce((state) => {
|
|
||||||
state[key] = value;
|
|
||||||
})
|
|
||||||
),
|
|
||||||
setStateFN: (key, value) => {
|
|
||||||
set(
|
|
||||||
produce((state) => {
|
|
||||||
if (typeof value === 'function') {
|
|
||||||
state[key] = (value as (value: any) => any)(state[key]);
|
|
||||||
} else {
|
|
||||||
console.error('value is not a function', value);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
updateSession: (setter: UpdateSessionType) => {
|
|
||||||
const curState = get();
|
|
||||||
|
|
||||||
const newSession: null | SessionDetail | void =
|
|
||||||
typeof setter === 'function'
|
|
||||||
? setter(curState?.session)
|
|
||||||
: typeof setter === 'object'
|
|
||||||
? (setter as SessionDetail)
|
|
||||||
: null;
|
|
||||||
if (newSession === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedState = {
|
|
||||||
...curState,
|
|
||||||
session: { ...curState.session, ...(newSession || {}) },
|
|
||||||
};
|
|
||||||
|
|
||||||
set((state) => {
|
|
||||||
state = {
|
|
||||||
...state,
|
|
||||||
session: { ...state.session, ...updatedState.session },
|
|
||||||
};
|
|
||||||
return state;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
//Load storage after the createStore function is executed.
|
|
||||||
try {
|
|
||||||
loadStorage()
|
|
||||||
.then((state) =>
|
|
||||||
GlobalStateStore.setState((s: GlobalStateStoreState) => ({
|
|
||||||
...s,
|
|
||||||
...state,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
.catch((e) => {
|
|
||||||
console.error('Error loading storage:', e);
|
|
||||||
});
|
|
||||||
|
|
||||||
GlobalStateStore.subscribe((state, previousState) => {
|
|
||||||
//console.log('subscribe', state, previousState)
|
|
||||||
saveStorage(state).catch((e) => {
|
|
||||||
console.error('Error saving storage:', e);
|
|
||||||
});
|
|
||||||
if (state.session.authtoken !== previousState.session.authtoken) {
|
|
||||||
setAuthTokenAPI(state.session.authtoken);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Error loading storage:', e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type-bounded version of useStore with shallow equality build in
|
|
||||||
*/
|
|
||||||
const createTypeBoundedUseStore = ((store) => (selector) =>
|
|
||||||
useStoreWithEqualityFn(store, selector, shallow)) as <S extends StoreApi<unknown>>(
|
|
||||||
store: S
|
|
||||||
) => {
|
|
||||||
(): ExtractState<S>;
|
|
||||||
<T>(selector: (state: ExtractState<S>) => T): T;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a hook to access the state of the `GlobalStateStore` with shallow equality
|
|
||||||
* checking in the selector function.
|
|
||||||
*
|
|
||||||
* @typeParam S - The type of the store
|
|
||||||
* @param store - The store to be used
|
|
||||||
* @returns A function that returns the state of the store, or a selected part of it
|
|
||||||
*/
|
|
||||||
const useGlobalStateStore = createTypeBoundedUseStore(GlobalStateStore);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the API URL in the program data store state.
|
|
||||||
*
|
|
||||||
* @param {string} url - The URL to set as the API URL.
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
const setApiURL = (url: string) => {
|
|
||||||
if (typeof GlobalStateStore?.setState !== 'function') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GlobalStateStore.setState((s: GlobalStateStoreState) => ({
|
|
||||||
...s,
|
|
||||||
session: {
|
|
||||||
...s.session,
|
|
||||||
apiURL: url,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the API URL from the session stored in the program data store.
|
|
||||||
*
|
|
||||||
* @return {string} The API URL from the session.
|
|
||||||
*/
|
|
||||||
const getApiURL = (): string => {
|
|
||||||
if (typeof GlobalStateStore?.setState !== 'function') {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const s = GlobalStateStore.getState();
|
|
||||||
return s.session?.apiURL;
|
|
||||||
};
|
|
||||||
|
|
||||||
export { getApiURL, GlobalStateStore, setApiURL, useGlobalStateStore };
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
import { type FunctionComponent } from 'react';
|
|
||||||
|
|
||||||
type DatabaseDetail = {
|
|
||||||
name?: string;
|
|
||||||
version?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ExtractState<S> = S extends { getState: () => infer X } ? X : never;
|
|
||||||
|
|
||||||
interface GlobalState {
|
|
||||||
[key: string]: any;
|
|
||||||
apiURL: string;
|
|
||||||
authtoken: string;
|
|
||||||
connected?: boolean;
|
|
||||||
environment?: 'development' | 'production';
|
|
||||||
error?: string;
|
|
||||||
globals?: Record<string, any>;
|
|
||||||
lastLoadTime?: string;
|
|
||||||
loading?: boolean;
|
|
||||||
menu?: Array<any>;
|
|
||||||
meta?: ProgramMetaData;
|
|
||||||
program: ProgramDetail;
|
|
||||||
|
|
||||||
updatedAt?: string;
|
|
||||||
user: UserDetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface GlobalStateStoreState extends GlobalState {
|
|
||||||
fetchData: (url?: string) => Promise<void>;
|
|
||||||
login: (sessionData?: string) => Promise<void>;
|
|
||||||
logout: () => Promise<void>;
|
|
||||||
onFetchSession?: (state: GlobalState) => Promise<GlobalState>;
|
|
||||||
setAuthToken: (token: string) => void;
|
|
||||||
setIsSecurity: (isSecurity: boolean) => void;
|
|
||||||
setState: <K extends keyof GlobalState>(key: K, value: GlobalState[K]) => void;
|
|
||||||
setStateFN: <K extends keyof GlobalState>(
|
|
||||||
key: K,
|
|
||||||
value: (current: GlobalState[K]) => Partial<GlobalState[K]>
|
|
||||||
) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProgramDetail = {
|
|
||||||
backend_version?: string;
|
|
||||||
biglogolink?: string;
|
|
||||||
database?: DatabaseDetail;
|
|
||||||
database_version?: string;
|
|
||||||
logolink?: string;
|
|
||||||
name: string;
|
|
||||||
programSummary?: string;
|
|
||||||
rid_owner?: number;
|
|
||||||
slug: string;
|
|
||||||
version?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface ProgramMetaData {
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ProgramWrapperProps {
|
|
||||||
apiURL?: string;
|
|
||||||
children: React.ReactNode | React.ReactNode[];
|
|
||||||
debugMode?: boolean;
|
|
||||||
fallback?: React.ReactNode | React.ReactNode[];
|
|
||||||
renderFallback?: boolean;
|
|
||||||
testMode?: boolean;
|
|
||||||
version?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserDetail = {
|
|
||||||
access_control?: boolean;
|
|
||||||
avatar_docid?: number;
|
|
||||||
fullnames?: string;
|
|
||||||
guid?: string;
|
|
||||||
id?: number;
|
|
||||||
isadmin?: boolean;
|
|
||||||
login?: string;
|
|
||||||
name?: string;
|
|
||||||
notice_msg?: string;
|
|
||||||
parameters?: Record<string, any>;
|
|
||||||
rid_hub?: number;
|
|
||||||
rid_user?: number;
|
|
||||||
secuser?: Record<string, any>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type {
|
|
||||||
ExtractState,
|
|
||||||
GlobalState,
|
|
||||||
GlobalStateStoreState,
|
|
||||||
ProgramDetail,
|
|
||||||
ProgramWrapperProps,
|
|
||||||
UserDetail,
|
|
||||||
};
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
import { createStore, entries, set, type UseStore } from 'idb-keyval';
|
|
||||||
|
|
||||||
const STORAGE_KEY = 'app-data';
|
|
||||||
|
|
||||||
const initilizeStore = () => {
|
|
||||||
if (indexedDB) {
|
|
||||||
try {
|
|
||||||
return createStore('programdata', 'programdata');
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to initialize indexedDB store: ', STORAGE_KEY, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const programDataIndexDBStore: null | UseStore = initilizeStore();
|
|
||||||
|
|
||||||
const skipKeysCallback = (dataKey: string, dataValue: any) => {
|
|
||||||
if (typeof dataValue === 'function') {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
dataKey === 'loading' ||
|
|
||||||
dataKey === 'error' ||
|
|
||||||
dataKey === 'security' ||
|
|
||||||
dataKey === 'meta' ||
|
|
||||||
dataKey === 'help'
|
|
||||||
) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dataValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
async function loadStorage<T = any>(storageKey?: string): Promise<T> {
|
|
||||||
if (indexedDB) {
|
|
||||||
try {
|
|
||||||
const storeValues = await entries(programDataIndexDBStore);
|
|
||||||
const obj: any = {};
|
|
||||||
|
|
||||||
storeValues.forEach((arr: string[]) => {
|
|
||||||
const k = String(arr[0]);
|
|
||||||
obj[k] = JSON.parse(arr[1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to load storage: ', storageKey ?? STORAGE_KEY, e);
|
|
||||||
}
|
|
||||||
} else if (localStorage) {
|
|
||||||
try {
|
|
||||||
const storagedata = localStorage.getItem(storageKey ?? STORAGE_KEY);
|
|
||||||
if (storagedata && storagedata.length > 0) {
|
|
||||||
const obj = JSON.parse(storagedata, (_dataKey, dataValue) => {
|
|
||||||
if (typeof dataValue === 'string' && dataValue.startsWith('function')) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return dataValue;
|
|
||||||
});
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
return {} as T;
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to load storage: ', storageKey ?? STORAGE_KEY, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {} as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function saveStorage<T = any>(data: T, storageKey?: string): Promise<T> {
|
|
||||||
if (indexedDB) {
|
|
||||||
try {
|
|
||||||
const keys = Object.keys(data as object).filter(
|
|
||||||
(key) =>
|
|
||||||
key !== 'loading' &&
|
|
||||||
key !== 'error' &&
|
|
||||||
key !== 'help' &&
|
|
||||||
key !== 'meta' &&
|
|
||||||
key !== 'security' &&
|
|
||||||
typeof data[key as keyof T] !== 'function'
|
|
||||||
);
|
|
||||||
const promises = keys.map((key) => {
|
|
||||||
return set(
|
|
||||||
key,
|
|
||||||
JSON.stringify((data as any)[key], skipKeysCallback) ?? '{}',
|
|
||||||
programDataIndexDBStore
|
|
||||||
);
|
|
||||||
});
|
|
||||||
await Promise.all(promises);
|
|
||||||
return data;
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to save indexedDB storage: ', storageKey ?? STORAGE_KEY, e);
|
|
||||||
}
|
|
||||||
} else if (localStorage) {
|
|
||||||
try {
|
|
||||||
const dataString = JSON.stringify(data, skipKeysCallback);
|
|
||||||
|
|
||||||
localStorage.setItem(storageKey ?? STORAGE_KEY, dataString ?? '{}');
|
|
||||||
return data;
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to save localStorage storage: ', storageKey ?? STORAGE_KEY, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {} as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { loadStorage, saveStorage };
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
export { ProgramDataWrapper } from './src/ProgramDataWrapper'
|
|
||||||
export {
|
|
||||||
getApiURL,
|
|
||||||
setApiURL,
|
|
||||||
programDataStore,
|
|
||||||
useProgramDataStore,
|
|
||||||
} from './src/store/ProgramDataStore.store'
|
|
||||||
|
|
||||||
export type * from './src/types'
|
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
"target": "es6",
|
"target": "es6",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"types": [
|
"types": [
|
||||||
"./global.d.ts"
|
"./global.d.ts",
|
||||||
|
"node"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
"ES2016",
|
"ES2016",
|
||||||
@@ -31,7 +32,8 @@
|
|||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"erasableSyntaxOnly": true,
|
"erasableSyntaxOnly": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"noUncheckedSideEffectImports": true
|
"noUncheckedSideEffectImports": true,
|
||||||
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src",
|
"src",
|
||||||
|
|||||||
@@ -19,7 +19,8 @@
|
|||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"erasableSyntaxOnly": true,
|
"erasableSyntaxOnly": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"noUncheckedSideEffectImports": true
|
"noUncheckedSideEffectImports": true,
|
||||||
|
"types": ["node"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"vite.config.ts"
|
"vite.config.ts"
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ export default defineConfig({
|
|||||||
tsconfigPath: './tsconfig.app.json',
|
tsconfigPath: './tsconfig.app.json',
|
||||||
compilerOptions: {
|
compilerOptions: {
|
||||||
noEmit: false,
|
noEmit: false,
|
||||||
|
skipLibCheck: true,
|
||||||
emitDeclarationOnly: true,
|
emitDeclarationOnly: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
],
|
],
|
||||||
publicDir: 'public',
|
publicDir: 'public',
|
||||||
build: {
|
build: {
|
||||||
|
|||||||
Reference in New Issue
Block a user