Newer
Older
import {
ObjectCacheAction, ObjectCacheActionTypes, AddToObjectCacheAction,
RemoveFromObjectCacheAction, ResetObjectCacheTimestampsAction
} from "./object-cache.actions";
import { CacheEntry } from "./cache-entry";
/**
* An interface to represent objects that can be cached
*
* A cacheable object should have a uuid
*/
export interface CacheableObject {
uuid: string;
}
export class ObjectCacheEntry implements CacheEntry {
data: CacheableObject;
timeAdded: number;
msToLive: number;
}
/**
* The ObjectCache State
*
* Consists of a map with UUIDs as keys,
* and ObjectCacheEntries as values
*/
export interface ObjectCacheState {
[uuid: string]: ObjectCacheEntry
}
// Object.create(null) ensures the object has no default js properties (e.g. `__proto__`)
const initialState: ObjectCacheState = Object.create(null);
/**
* The ObjectCache Reducer
*
* @param state
* the current state
* @param action
* the action to perform on the state
* @return ObjectCacheState
* the new state
*/
export const objectCacheReducer = (state = initialState, action: ObjectCacheAction): ObjectCacheState => {
switch (action.type) {
case ObjectCacheActionTypes.ADD: {
return addToObjectCache(state, <AddToObjectCacheAction>action);
}
case ObjectCacheActionTypes.REMOVE: {
return removeFromObjectCache(state, <RemoveFromObjectCacheAction>action)
}
case ObjectCacheActionTypes.RESET_TIMESTAMPS: {
return resetObjectCacheTimestamps(state, <ResetObjectCacheTimestampsAction>action)
}
/**
* Add an object to the cache
*
* @param state
* the current state
* @param action
* an AddToObjectCacheAction
* @return ObjectCacheState
* the new state, with the object added, or overwritten.
*/
function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheAction): ObjectCacheState {
return Object.assign({}, state, {
[action.payload.objectToCache.uuid]: {
data: action.payload.objectToCache,
timeAdded: action.payload.timeAdded,
msToLive: action.payload.msToLive
}
});
}
/**
* Remove an object from the cache
*
* @param state
* the current state
* @param action
* an RemoveFromObjectCacheAction
* @return ObjectCacheState
* the new state, with the object removed if it existed.
*/
function removeFromObjectCache(state: ObjectCacheState, action: RemoveFromObjectCacheAction): ObjectCacheState {
if (hasValue(state[action.payload])) {
let newObjectCache = Object.assign({}, state);
delete newObjectCache[action.payload];
return newObjectCache;
}
else {
return state;
}
}
/**
* Set the timeAdded timestamp of every cached object to the specified value
*
* @param state
* the current state
* @param action
* a ResetObjectCacheTimestampsAction
* @return ObjectCacheState
* the new state, with all timeAdded timestamps set to the specified value
*/
function resetObjectCacheTimestamps(state: ObjectCacheState, action: ResetObjectCacheTimestampsAction): ObjectCacheState {
let newState = Object.create(null);
Object.keys(state).forEach(key => {
newState[key] = Object.assign({}, state[key], {
timeAdded: action.payload
});
});
return newState;
}