mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
implementation of server synchronization
This commit is contained in:
@@ -20,7 +20,12 @@ module.exports = {
|
||||
// NOTE: how long should objects be cached for by default
|
||||
msToLive: 15 * 60 * 1000, // 15 minutes
|
||||
// msToLive: 1000, // 15 minutes
|
||||
control: 'max-age=60' // revalidate browser
|
||||
control: 'max-age=60', // revalidate browser
|
||||
autoSync: {
|
||||
defaultTime: 0,
|
||||
maxBufferSize: 100,
|
||||
timePerMethod: {'Patch': 30} //time in seconds
|
||||
}
|
||||
},
|
||||
// Form settings
|
||||
form: {
|
||||
|
50
src/app/core/cache/object-cache.actions.ts
vendored
50
src/app/core/cache/object-cache.actions.ts
vendored
@@ -11,7 +11,8 @@ export const ObjectCacheActionTypes = {
|
||||
ADD: type('dspace/core/cache/object/ADD'),
|
||||
REMOVE: type('dspace/core/cache/object/REMOVE'),
|
||||
RESET_TIMESTAMPS: type('dspace/core/cache/object/RESET_TIMESTAMPS'),
|
||||
PATCH: type('dspace/core/cache/object/PATCH')
|
||||
ADD_PATCH: type('dspace/core/cache/object/ADD_PATCH'),
|
||||
APPLY_PATCH: type('dspace/core/cache/object/APPLY_PATCH')
|
||||
};
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
@@ -56,11 +57,11 @@ export class RemoveFromObjectCacheAction implements Action {
|
||||
/**
|
||||
* Create a new RemoveFromObjectCacheAction
|
||||
*
|
||||
* @param uuid
|
||||
* the UUID of the object to remove
|
||||
* @param href
|
||||
* the unique href of the object to remove
|
||||
*/
|
||||
constructor(uuid: string) {
|
||||
this.payload = uuid;
|
||||
constructor(href: string) {
|
||||
this.payload = href;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,25 +84,43 @@ export class ResetObjectCacheTimestampsAction implements Action {
|
||||
}
|
||||
|
||||
/**
|
||||
* An ngrx action to add new operations to a specified cached objects
|
||||
* An ngrx action to add new operations to a specified cached object
|
||||
*/
|
||||
export class PatchObjectCacheAction implements Action {
|
||||
type = ObjectCacheActionTypes.PATCH;
|
||||
export class AddPatchObjectCacheAction implements Action {
|
||||
type = ObjectCacheActionTypes.ADD_PATCH;
|
||||
payload: {
|
||||
uuid: string,
|
||||
href: string,
|
||||
operations: Operation[]
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new PatchObjectCacheAction
|
||||
* Create a new AddPatchObjectCacheAction
|
||||
*
|
||||
* @param uuid
|
||||
* the uuid of the object that should be updated
|
||||
* @param href
|
||||
* the unique href of the object that should be updated
|
||||
* @param operations
|
||||
* the list of operations to add
|
||||
*/
|
||||
constructor(uuid: string, operations: Operation[]) {
|
||||
this.payload = { uuid, operations };
|
||||
constructor(href: string, operations: Operation[]) {
|
||||
this.payload = { href, operations };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An ngrx action to apply all existing operations to a specified cached object
|
||||
*/
|
||||
export class ApplyPatchObjectCacheAction implements Action {
|
||||
type = ObjectCacheActionTypes.APPLY_PATCH;
|
||||
payload: string;
|
||||
|
||||
/**
|
||||
* Create a new ApplyPatchObjectCacheAction
|
||||
*
|
||||
* @param href
|
||||
* the unique href of the object that should be updated
|
||||
*/
|
||||
constructor(href: string) {
|
||||
this.payload = href;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,4 +133,5 @@ export type ObjectCacheAction
|
||||
= AddToObjectCacheAction
|
||||
| RemoveFromObjectCacheAction
|
||||
| ResetObjectCacheTimestampsAction
|
||||
| PatchObjectCacheAction;
|
||||
| AddPatchObjectCacheAction
|
||||
| ApplyPatchObjectCacheAction;
|
||||
|
63
src/app/core/cache/object-cache.reducer.ts
vendored
63
src/app/core/cache/object-cache.reducer.ts
vendored
@@ -1,11 +1,15 @@
|
||||
import {
|
||||
ObjectCacheAction, ObjectCacheActionTypes, AddToObjectCacheAction,
|
||||
RemoveFromObjectCacheAction, ResetObjectCacheTimestampsAction, PatchObjectCacheAction
|
||||
ObjectCacheAction,
|
||||
ObjectCacheActionTypes,
|
||||
AddToObjectCacheAction,
|
||||
RemoveFromObjectCacheAction,
|
||||
ResetObjectCacheTimestampsAction,
|
||||
AddPatchObjectCacheAction, ApplyPatchObjectCacheAction
|
||||
} from './object-cache.actions';
|
||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { CacheEntry } from './cache-entry';
|
||||
import { ResourceType } from '../shared/resource-type';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { applyPatch, Operation } from 'fast-json-patch';
|
||||
|
||||
export enum DirtyType {
|
||||
Created = 'Created',
|
||||
@@ -13,7 +17,11 @@ export enum DirtyType {
|
||||
Deleted = 'Deleted'
|
||||
}
|
||||
|
||||
/**
|
||||
export interface Patch {
|
||||
uuid?: string;
|
||||
operations: Operation[];
|
||||
}
|
||||
/**conca
|
||||
* An interface to represent objects that can be cached
|
||||
*
|
||||
* A cacheable object should have a self link
|
||||
@@ -37,7 +45,8 @@ export class ObjectCacheEntry implements CacheEntry {
|
||||
timeAdded: number;
|
||||
msToLive: number;
|
||||
requestHref: string;
|
||||
operations: Operation[];
|
||||
patches: Patch[] = [];
|
||||
isDirty: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,9 +87,14 @@ export function objectCacheReducer(state = initialState, action: ObjectCacheActi
|
||||
return resetObjectCacheTimestamps(state, action as ResetObjectCacheTimestampsAction)
|
||||
}
|
||||
|
||||
case ObjectCacheActionTypes.PATCH: {
|
||||
return patchObjectCache(state, action as PatchObjectCacheAction);
|
||||
case ObjectCacheActionTypes.ADD_PATCH: {
|
||||
return addPatchObjectCache(state, action as AddPatchObjectCacheAction);
|
||||
}
|
||||
|
||||
case ObjectCacheActionTypes.APPLY_PATCH: {
|
||||
return applyPatchObjectCache(state, action as ApplyPatchObjectCacheAction);
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
@@ -104,7 +118,7 @@ function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheActio
|
||||
timeAdded: action.payload.timeAdded,
|
||||
msToLive: action.payload.msToLive,
|
||||
requestHref: action.payload.requestHref,
|
||||
operations: []
|
||||
isDirty: false
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -156,16 +170,41 @@ function resetObjectCacheTimestamps(state: ObjectCacheState, action: ResetObject
|
||||
* @param state
|
||||
* the current state
|
||||
* @param action
|
||||
* a PatchObjectCacheAction
|
||||
* an AddPatchObjectCacheAction
|
||||
* @return ObjectCacheState
|
||||
* the new state, with the new operations added to the state of the specified ObjectCacheEntry
|
||||
*/
|
||||
function patchObjectCache(state: ObjectCacheState, action: PatchObjectCacheAction): ObjectCacheState {
|
||||
const uuid = action.payload.uuid;
|
||||
function addPatchObjectCache(state: ObjectCacheState, action: AddPatchObjectCacheAction): ObjectCacheState {
|
||||
const uuid = action.payload.href;
|
||||
const operations = action.payload.operations;
|
||||
const newState = Object.assign({}, state);
|
||||
if (hasValue(newState[uuid])) {
|
||||
newState[uuid].operations = state[uuid].operations.concat(operations);
|
||||
const patches = newState[uuid].patches;
|
||||
newState[uuid].patches = [...patches, {operations} as Patch];
|
||||
newState[uuid].isDirty = true;
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the list of patch operations to a cached object
|
||||
*
|
||||
* @param state
|
||||
* the current state
|
||||
* @param action
|
||||
* an ApplyPatchObjectCacheAction
|
||||
* @return ObjectCacheState
|
||||
* the new state, with the new operations applied to the state of the specified ObjectCacheEntry
|
||||
*/
|
||||
function applyPatchObjectCache(state: ObjectCacheState, action: ApplyPatchObjectCacheAction): ObjectCacheState {
|
||||
const uuid = action.payload;
|
||||
const newState = Object.assign({}, state);
|
||||
if (hasValue(newState[uuid])) {
|
||||
// flatten two dimensional array
|
||||
const flatPatch: Operation[] = [].concat(...newState[uuid].patches);
|
||||
const newData = applyPatch( newState[uuid].data, flatPatch);
|
||||
newState[uuid].data = newData.newDocument;
|
||||
newState[uuid].patches = [];
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
|
47
src/app/core/cache/object-cache.service.ts
vendored
47
src/app/core/cache/object-cache.service.ts
vendored
@@ -7,8 +7,8 @@ import { IndexName } from '../index/index.reducer';
|
||||
|
||||
import { CacheableObject, ObjectCacheEntry } from './object-cache.reducer';
|
||||
import {
|
||||
AddToObjectCacheAction,
|
||||
PatchObjectCacheAction,
|
||||
AddPatchObjectCacheAction,
|
||||
AddToObjectCacheAction, ApplyPatchObjectCacheAction,
|
||||
RemoveFromObjectCacheAction
|
||||
} from './object-cache.actions';
|
||||
import { hasNoValue, isNotEmpty } from '../../shared/empty.util';
|
||||
@@ -18,13 +18,15 @@ import { pathSelector } from '../shared/selectors';
|
||||
import { NormalizedObjectFactory } from './models/normalized-object-factory';
|
||||
import { NormalizedObject } from './models/normalized-object.model';
|
||||
import { applyPatch, Operation } from 'fast-json-patch';
|
||||
import { RestRequestMethod } from '../data/request.models';
|
||||
import { AddToSSBAction } from './server-sync-buffer.actions';
|
||||
|
||||
function selfLinkFromUuidSelector(uuid: string): MemoizedSelector<CoreState, string> {
|
||||
return pathSelector<CoreState, string>(coreSelector, 'index', IndexName.OBJECT, uuid);
|
||||
}
|
||||
|
||||
function entryFromSelfLinkSelector(selfLink: string): MemoizedSelector<CoreState, ObjectCacheEntry> {
|
||||
return pathSelector<CoreState, ObjectCacheEntry>(coreSelector, 'data/object', selfLink);
|
||||
return pathSelector<CoreState, ObjectCacheEntry>(coreSelector, 'cache/object', selfLink);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,10 +54,10 @@ export class ObjectCacheService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the object with the supplied UUID from the cache
|
||||
* Remove the object with the supplied href from the cache
|
||||
*
|
||||
* @param uuid
|
||||
* The UUID of the object to be removed
|
||||
* @param href
|
||||
* The unique href of the object to be removed
|
||||
*/
|
||||
remove(uuid: string): void {
|
||||
this.store.dispatch(new RemoveFromObjectCacheAction(uuid));
|
||||
@@ -87,13 +89,17 @@ export class ObjectCacheService {
|
||||
|
||||
getBySelfLink<T extends NormalizedObject>(selfLink: string): Observable<T> {
|
||||
return this.getEntry(selfLink).pipe(
|
||||
map((entry: ObjectCacheEntry) => {
|
||||
// flatten two dimensional array
|
||||
const flatPatch: Operation[] = [].concat(...entry.patches);
|
||||
const patchedData = applyPatch(entry.data, flatPatch).newDocument;
|
||||
return Object.assign({}, entry, { data: patchedData });
|
||||
}
|
||||
),
|
||||
map((entry: ObjectCacheEntry) => {
|
||||
const type: GenericConstructor<NormalizedObject> = NormalizedObjectFactory.getConstructor(entry.data.type);
|
||||
return Object.assign(new type(), entry.data) as T
|
||||
}),
|
||||
// map((entry: ObjectCacheEntry) =>
|
||||
// applyPatch(entry.data, entry.operations).newDocument
|
||||
// )
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -205,14 +211,16 @@ export class ObjectCacheService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add operations to a the existing list of operations for an ObjectCacheEntry
|
||||
* Add operations to the existing list of operations for an ObjectCacheEntry
|
||||
* Makes sure the ServerSyncBuffer for this ObjectCacheEntry is updated
|
||||
* @param {string} uuid
|
||||
* the uuid of the ObjectCacheEntry
|
||||
* @param {Operation[]} patch
|
||||
* list of operations to perform
|
||||
*/
|
||||
private addOperations(uuid: string, patch: Operation[]) {
|
||||
this.store.dispatch(new PatchObjectCacheAction(uuid, patch));
|
||||
private addPatch(uuid: string, patch: Operation[]) {
|
||||
this.store.dispatch(new AddPatchObjectCacheAction(uuid, patch));
|
||||
this.store.dispatch(new AddToSSBAction(uuid, RestRequestMethod.Patch));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,6 +232,17 @@ export class ObjectCacheService {
|
||||
* false if the entry is there are no operations left in the ObjectCacheEntry, true otherwise
|
||||
*/
|
||||
private isDirty(entry: ObjectCacheEntry): boolean {
|
||||
return isNotEmpty(entry.operations);
|
||||
return isNotEmpty(entry.patches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the existing operations on an ObjectCacheEntry in the store
|
||||
* NB: this does not make any server side changes
|
||||
* @param {string} uuid
|
||||
* the uuid of the ObjectCacheEntry
|
||||
*/
|
||||
private applyPatchesToCachedObject(uuid: string) {
|
||||
this.store.dispatch(new ApplyPatchObjectCacheAction(uuid));
|
||||
}
|
||||
|
||||
}
|
||||
|
2
src/app/core/cache/response-cache.service.ts
vendored
2
src/app/core/cache/response-cache.service.ts
vendored
@@ -12,7 +12,7 @@ import { coreSelector, CoreState } from '../core.reducers';
|
||||
import { pathSelector } from '../shared/selectors';
|
||||
|
||||
function entryFromKeySelector(key: string): MemoizedSelector<CoreState, ResponseCacheEntry> {
|
||||
return pathSelector<CoreState, ResponseCacheEntry>(coreSelector, 'data/response', key);
|
||||
return pathSelector<CoreState, ResponseCacheEntry>(coreSelector, 'cache/response', key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
83
src/app/core/cache/server-sync-buffer.actions.ts
vendored
Normal file
83
src/app/core/cache/server-sync-buffer.actions.ts
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { type } from '../../shared/ngrx/type';
|
||||
import { CacheableObject } from './object-cache.reducer';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { RestRequest, RestRequestMethod } from '../data/request.models';
|
||||
|
||||
/**
|
||||
* The list of ServerSyncBufferAction type definitions
|
||||
*/
|
||||
export const ServerSyncBufferActionTypes = {
|
||||
ADD: type('dspace/core/cache/syncbuffer/ADD'),
|
||||
COMMIT: type('dspace/core/cache/syncbuffer/COMMIT'),
|
||||
EMPTY: type('dspace/core/cache/syncbuffer/EMPTY'),
|
||||
};
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
|
||||
/**
|
||||
* An ngrx action to add a new cached object to the server's sync buffer
|
||||
*/
|
||||
export class AddToSSBAction implements Action {
|
||||
type = ServerSyncBufferActionTypes.ADD;
|
||||
payload: {
|
||||
href: string,
|
||||
method: RestRequestMethod
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new AddToSSBAction
|
||||
*
|
||||
* @param href
|
||||
* the unique href of the cached object entry that should be updated
|
||||
*/
|
||||
constructor(href: string, method: RestRequestMethod) {
|
||||
this.payload = { href, method };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An ngrx action to commit everything (for a certain method, when specified) in the ServerSyncBuffer to the server
|
||||
*/
|
||||
export class CommitSSBAction implements Action {
|
||||
type = ServerSyncBufferActionTypes.COMMIT;
|
||||
payload?: RestRequestMethod;
|
||||
|
||||
/**
|
||||
* Create a new CommitSSBAction
|
||||
*
|
||||
* @param method
|
||||
* an optional method for which the ServerSyncBuffer should send its entries to the server
|
||||
*/
|
||||
constructor(method?: RestRequestMethod) {
|
||||
this.payload = method;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* An ngrx action to remove everything (for a certain method, when specified) from the ServerSyncBuffer to the server
|
||||
*/
|
||||
export class EmptySSBAction implements Action {
|
||||
type = ServerSyncBufferActionTypes.EMPTY;
|
||||
payload?: RestRequestMethod;
|
||||
|
||||
/**
|
||||
* Create a new EmptySSBAction
|
||||
*
|
||||
* @param method
|
||||
* an optional method for which the ServerSyncBuffer should remove its entries
|
||||
*/
|
||||
constructor(method?: RestRequestMethod) {
|
||||
this.payload = method;
|
||||
}
|
||||
}
|
||||
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
||||
/**
|
||||
* A type to encompass all ServerSyncBufferActions
|
||||
*/
|
||||
export type ServerSyncBufferAction
|
||||
= AddToSSBAction
|
||||
| CommitSSBAction
|
||||
| EmptySSBAction
|
55
src/app/core/cache/server-sync-buffer.effects.ts
vendored
Normal file
55
src/app/core/cache/server-sync-buffer.effects.ts
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import { delay, exhaustMap, filter, first, map } from 'rxjs/operators';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Actions, Effect, ofType } from '@ngrx/effects';
|
||||
import {
|
||||
AddToSSBAction,
|
||||
CommitSSBAction,
|
||||
EmptySSBAction,
|
||||
ServerSyncBufferActionTypes
|
||||
} from './server-sync-buffer.actions';
|
||||
import { GLOBAL_CONFIG } from '../../../config';
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { select, Store } from '@ngrx/store';
|
||||
import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { PutRequest } from '../data/request.models';
|
||||
|
||||
@Injectable()
|
||||
export class ObjectCacheEffects {
|
||||
@Effect() setTimeoutForServerSync = this.actions$
|
||||
.pipe(ofType(ServerSyncBufferActionTypes.ADD),
|
||||
exhaustMap((action: AddToSSBAction) => {
|
||||
const autoSyncConfig = this.EnvConfig.cache.autoSync;
|
||||
const timeoutInSeconds = autoSyncConfig.timePerMethod[action.type] || autoSyncConfig.defaultTime;
|
||||
return observableOf(new CommitSSBAction(action.payload.method)).pipe(delay( timeoutInSeconds * 1000))
|
||||
})
|
||||
);
|
||||
|
||||
@Effect() commitServerSyncBuffer = this.actions$
|
||||
.pipe(ofType(ServerSyncBufferActionTypes.COMMIT),
|
||||
map((action: CommitSSBAction) => {
|
||||
this.store.pipe(
|
||||
select(serverSyncBufferSelector),
|
||||
first()
|
||||
).subscribe((bufferState: ServerSyncBufferState) => {
|
||||
bufferState.buffer
|
||||
.filter((entry: ServerSyncBufferEntry) => entry.method === action.payload)
|
||||
.forEach((entry: ServerSyncBufferEntry) => {
|
||||
this.requestService.configure(new PutRequest(this.requestService.generateRequestId(), ,))
|
||||
})
|
||||
});
|
||||
return new EmptySSBAction(action.payload);
|
||||
})
|
||||
);
|
||||
|
||||
constructor(private actions$: Actions,
|
||||
private store: Store<CoreState>,
|
||||
private requestService: RequestService,
|
||||
@Inject(GLOBAL_CONFIG) private EnvConfig: GlobalConfig) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export const serverSyncBufferSelector = (state: CoreState) => state['cache/syncbuffer'];
|
92
src/app/core/cache/server-sync-buffer.reducer.ts
vendored
Normal file
92
src/app/core/cache/server-sync-buffer.reducer.ts
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import { RestRequestMethod } from '../data/request.models';
|
||||
import { hasNoValue, hasValue } from '../../shared/empty.util';
|
||||
import {
|
||||
AddToSSBAction,
|
||||
EmptySSBAction,
|
||||
ServerSyncBufferAction,
|
||||
ServerSyncBufferActionTypes
|
||||
} from './server-sync-buffer.actions';
|
||||
|
||||
/**
|
||||
* An entry in the ServerSyncBufferState
|
||||
* href: unique href of an ObjectCacheEntry
|
||||
* method: RestRequestMethod type
|
||||
*/
|
||||
export class ServerSyncBufferEntry {
|
||||
href: string;
|
||||
method: RestRequestMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ServerSyncBuffer State
|
||||
*
|
||||
* Consists list of ServerSyncBufferState
|
||||
*/
|
||||
export interface ServerSyncBufferState {
|
||||
buffer: ServerSyncBufferEntry[];
|
||||
}
|
||||
|
||||
// Object.create(null) ensures the object has no default js properties (e.g. `__proto__`)
|
||||
const initialState: ServerSyncBufferState = { buffer: [] };
|
||||
|
||||
/**
|
||||
* The ServerSyncBuffer Reducer
|
||||
*
|
||||
* @param state
|
||||
* the current state
|
||||
* @param action
|
||||
* the action to perform on the state
|
||||
* @return ServerSyncBufferState
|
||||
* the new state
|
||||
*/
|
||||
export function serverSyncBufferReducer(state = initialState, action: ServerSyncBufferAction): ServerSyncBufferState {
|
||||
switch (action.type) {
|
||||
|
||||
case ServerSyncBufferActionTypes.ADD: {
|
||||
return addToServerSyncQueue(state, action as AddToSSBAction)
|
||||
}
|
||||
|
||||
case ServerSyncBufferActionTypes.EMPTY: {
|
||||
return emptyServerSyncQueue(state, action as EmptySSBAction);
|
||||
}
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new entry to the buffer with a specified method
|
||||
*
|
||||
* @param state
|
||||
* the current state
|
||||
* @param action
|
||||
* an AddToSSBAction
|
||||
* @return ServerSyncBufferState
|
||||
* the new state, with a new entry added to the buffer
|
||||
*/
|
||||
function addToServerSyncQueue(state: ServerSyncBufferState, action: AddToSSBAction): ServerSyncBufferState {
|
||||
const actionEntry = action.payload as ServerSyncBufferEntry;
|
||||
if (hasNoValue(state.buffer.find((entry) => entry.href === actionEntry.href && entry.method === actionEntry.method))) {
|
||||
return Object.assign({}, state, { buffer: state.buffer.concat(actionEntry) });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all ServerSyncBuffers entry from the buffer with a specified method
|
||||
* If no method is specified, empty the whole buffer
|
||||
*
|
||||
* @param state
|
||||
* the current state
|
||||
* @param action
|
||||
* an AddToSSBAction
|
||||
* @return ServerSyncBufferState
|
||||
* the new state, with a new entry added to the buffer
|
||||
*/
|
||||
function emptyServerSyncQueue(state: ServerSyncBufferState, action: EmptySSBAction): ServerSyncBufferState {
|
||||
let newBuffer = [];
|
||||
if (hasValue(action.payload)) {
|
||||
newBuffer = state.buffer.filter((entry) => entry.method !== action.payload);
|
||||
}
|
||||
return Object.assign({}, state, { buffer: newBuffer });
|
||||
}
|
@@ -5,18 +5,21 @@ import { objectCacheReducer, ObjectCacheState } from './cache/object-cache.reduc
|
||||
import { indexReducer, IndexState } from './index/index.reducer';
|
||||
import { requestReducer, RequestState } from './data/request.reducer';
|
||||
import { authReducer, AuthState } from './auth/auth.reducer';
|
||||
import { serverSyncBufferReducer, ServerSyncBufferState } from './cache/server-sync-buffer.reducer';
|
||||
|
||||
export interface CoreState {
|
||||
'data/object': ObjectCacheState,
|
||||
'data/response': ResponseCacheState,
|
||||
'cache/object': ObjectCacheState,
|
||||
'cache/response': ResponseCacheState,
|
||||
'cache/syncbuffer': ServerSyncBufferState,
|
||||
'data/request': RequestState,
|
||||
'index': IndexState,
|
||||
'auth': AuthState,
|
||||
}
|
||||
|
||||
export const coreReducers: ActionReducerMap<CoreState> = {
|
||||
'data/object': objectCacheReducer,
|
||||
'data/response': responseCacheReducer,
|
||||
'cache/object': objectCacheReducer,
|
||||
'cache/response': responseCacheReducer,
|
||||
'cache/syncbuffer': serverSyncBufferReducer,
|
||||
'data/request': requestReducer,
|
||||
'index': indexReducer,
|
||||
'auth': authReducer
|
||||
|
12
src/config/auto-sync-config.interface.ts
Normal file
12
src/config/auto-sync-config.interface.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { RestRequestMethod } from '../app/core/data/request.models';
|
||||
|
||||
/* enum indices */
|
||||
type TimePerMethod = {
|
||||
[method in RestRequestMethod]: number;
|
||||
};
|
||||
|
||||
export interface AutoSyncConfig {
|
||||
defaultTime: number;
|
||||
timePerMethod: TimePerMethod;
|
||||
maxBufferSize: number;
|
||||
};
|
@@ -1,6 +1,8 @@
|
||||
import { Config } from './config.interface';
|
||||
import { AutoSyncConfig } from './auto-sync-config.interface';
|
||||
|
||||
export interface CacheConfig extends Config {
|
||||
msToLive: number,
|
||||
control: string
|
||||
control: string,
|
||||
autoSync: AutoSyncConfig
|
||||
}
|
||||
|
Reference in New Issue
Block a user