Split the store construction to a separate file.
parent
a4fca53541
commit
7e406e4f77
@ -0,0 +1,165 @@
|
|||||||
|
import * as localforage from 'localforage';
|
||||||
|
import { combineReducers } from 'redux';
|
||||||
|
import { createMigrate, persistReducer, createTransform } from 'redux-persist';
|
||||||
|
import session from 'redux-persist/lib/storage/session';
|
||||||
|
|
||||||
|
import { List, Map as ImmutableMap } from 'immutable';
|
||||||
|
|
||||||
|
import * as EteSync from '../api/EteSync';
|
||||||
|
import {
|
||||||
|
JournalsData, FetchType, EntriesData, EntriesFetchRecord, UserInfoData, JournalsFetchRecord, UserInfoFetchRecord,
|
||||||
|
CredentialsTypeRemote, JournalsType, EntriesType, UserInfoType, SettingsType,
|
||||||
|
fetchCount, journals, entries, credentials, userInfo, settingsReducer, encryptionKeyReducer,
|
||||||
|
} from './reducers';
|
||||||
|
|
||||||
|
export interface StoreState {
|
||||||
|
fetchCount: number;
|
||||||
|
credentials: CredentialsTypeRemote;
|
||||||
|
settings: SettingsType;
|
||||||
|
encryptionKey: {key: string};
|
||||||
|
cache: {
|
||||||
|
journals: JournalsType;
|
||||||
|
entries: EntriesType;
|
||||||
|
userInfo: UserInfoType;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const settingsPersistConfig = {
|
||||||
|
key: 'settings',
|
||||||
|
storage: localforage,
|
||||||
|
};
|
||||||
|
|
||||||
|
const credentialsPersistConfig = {
|
||||||
|
key: 'credentials',
|
||||||
|
storage: localforage,
|
||||||
|
whitelist: ['value'],
|
||||||
|
};
|
||||||
|
|
||||||
|
const encryptionKeyPersistConfig = {
|
||||||
|
key: 'encryptionKey',
|
||||||
|
storage: session,
|
||||||
|
};
|
||||||
|
|
||||||
|
const journalsSerialize = (state: JournalsData) => {
|
||||||
|
if (state === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.map((x, uid) => x.serialize()).toJS();
|
||||||
|
};
|
||||||
|
|
||||||
|
const journalsDeserialize = (state: {}) => {
|
||||||
|
if (state === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newState = new Map<string, EteSync.Journal>();
|
||||||
|
Object.keys(state).forEach((uid) => {
|
||||||
|
const x = state[uid];
|
||||||
|
const ret = new EteSync.Journal(x.version);
|
||||||
|
ret.deserialize(x);
|
||||||
|
newState.set(uid, ret);
|
||||||
|
});
|
||||||
|
return ImmutableMap(newState);
|
||||||
|
};
|
||||||
|
|
||||||
|
const entriesSerialize = (state: FetchType<EntriesData>) => {
|
||||||
|
if ((state === null) || (state.value == null)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.value.map((x) => x.serialize()).toJS();
|
||||||
|
};
|
||||||
|
|
||||||
|
const entriesDeserialize = (state: EteSync.EntryJson[]): FetchType<EntriesData> => {
|
||||||
|
if (state === null) {
|
||||||
|
return new EntriesFetchRecord({value: null});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EntriesFetchRecord({value: List(state.map((x: any) => {
|
||||||
|
let ret = new EteSync.Entry();
|
||||||
|
ret.deserialize(x);
|
||||||
|
return ret;
|
||||||
|
}))});
|
||||||
|
};
|
||||||
|
|
||||||
|
const userInfoSerialize = (state: FetchType<UserInfoData>) => {
|
||||||
|
if ((state === null) || (state.value == null)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.value.serialize();
|
||||||
|
};
|
||||||
|
|
||||||
|
const userInfoDeserialize = (state: EteSync.UserInfoJson) => {
|
||||||
|
if (state === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ret = new EteSync.UserInfo(state.owner!, state.version);
|
||||||
|
ret.deserialize(state);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
const cacheSerialize = (state: any, key: string) => {
|
||||||
|
if (key === 'entries') {
|
||||||
|
let ret = {};
|
||||||
|
state.forEach((value: FetchType<EntriesData>, mapKey: string) => {
|
||||||
|
ret[mapKey] = entriesSerialize(value);
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
} else if (key === 'journals') {
|
||||||
|
return journalsSerialize(state.value);
|
||||||
|
} else if (key === 'userInfo') {
|
||||||
|
return userInfoSerialize(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const cacheDeserialize = (state: any, key: string) => {
|
||||||
|
if (key === 'entries') {
|
||||||
|
let ret = {};
|
||||||
|
Object.keys(state).forEach((mapKey) => {
|
||||||
|
ret[mapKey] = entriesDeserialize(state[mapKey]);
|
||||||
|
});
|
||||||
|
return ImmutableMap(ret);
|
||||||
|
} else if (key === 'journals') {
|
||||||
|
return new JournalsFetchRecord({value: journalsDeserialize(state)});
|
||||||
|
} else if (key === 'userInfo') {
|
||||||
|
return new UserInfoFetchRecord({value: userInfoDeserialize(state)});
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const cacheMigrations = {
|
||||||
|
0: (state: any) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
journals: undefined
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const cachePersistConfig = {
|
||||||
|
key: 'cache',
|
||||||
|
version: 1,
|
||||||
|
storage: localforage,
|
||||||
|
transforms: [createTransform(cacheSerialize, cacheDeserialize)],
|
||||||
|
migrate: createMigrate(cacheMigrations, { debug: false}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const reducers = combineReducers({
|
||||||
|
fetchCount,
|
||||||
|
settings: persistReducer(settingsPersistConfig, settingsReducer),
|
||||||
|
credentials: persistReducer(credentialsPersistConfig, credentials),
|
||||||
|
encryptionKey: persistReducer(encryptionKeyPersistConfig, encryptionKeyReducer),
|
||||||
|
cache: persistReducer(cachePersistConfig, combineReducers({
|
||||||
|
entries,
|
||||||
|
journals,
|
||||||
|
userInfo,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default reducers;
|
Loading…
Reference in New Issue