|
@@ -1,4 +1,4 @@
|
|
|
-import { EventSource, EventSourceHash, getEventSourceDef, EventSourceDef } from '../structs/event-source'
|
|
|
|
|
|
|
+import { EventSource, EventSourceHash, getEventSourceDef, doesSourceNeedRange } from '../structs/event-source'
|
|
|
import Calendar from '../Calendar'
|
|
import Calendar from '../Calendar'
|
|
|
import { arrayToHash, assignTo, filterHash } from '../util/object'
|
|
import { arrayToHash, assignTo, filterHash } from '../util/object'
|
|
|
import { DateRange } from '../datelib/date-range'
|
|
import { DateRange } from '../datelib/date-range'
|
|
@@ -6,99 +6,105 @@ import { warn } from '../util/misc'
|
|
|
import { DateProfile } from '../DateProfileGenerator'
|
|
import { DateProfile } from '../DateProfileGenerator'
|
|
|
import { Action, SimpleError } from './types'
|
|
import { Action, SimpleError } from './types'
|
|
|
|
|
|
|
|
-export default function(eventSourceHash: EventSourceHash, action: Action, dateProfile: DateProfile | null, calendar: Calendar): EventSourceHash {
|
|
|
|
|
|
|
+export default function(eventSources: EventSourceHash, action: Action, dateProfile: DateProfile | null, calendar: Calendar): EventSourceHash {
|
|
|
switch (action.type) {
|
|
switch (action.type) {
|
|
|
|
|
|
|
|
case 'ADD_EVENT_SOURCES': // already parsed
|
|
case 'ADD_EVENT_SOURCES': // already parsed
|
|
|
- return addSources(eventSourceHash, action.sources, dateProfile, calendar)
|
|
|
|
|
|
|
+ return addSources(eventSources, action.sources, dateProfile ? dateProfile.activeRange : null, calendar)
|
|
|
|
|
|
|
|
case 'REMOVE_EVENT_SOURCE':
|
|
case 'REMOVE_EVENT_SOURCE':
|
|
|
- return removeSource(eventSourceHash, action.sourceId)
|
|
|
|
|
|
|
+ return removeSource(eventSources, action.sourceId)
|
|
|
|
|
|
|
|
case 'SET_DATE_PROFILE':
|
|
case 'SET_DATE_PROFILE':
|
|
|
- return fetchDirtySources(eventSourceHash, action.dateProfile, calendar)
|
|
|
|
|
|
|
+ return fetchDirtySources(eventSources, action.dateProfile.activeRange, calendar)
|
|
|
|
|
|
|
|
case 'FETCH_EVENT_SOURCES':
|
|
case 'FETCH_EVENT_SOURCES':
|
|
|
- if (dateProfile) {
|
|
|
|
|
- return fetchSourcesByIds(eventSourceHash, action.sourceIds || null, dateProfile, calendar)
|
|
|
|
|
- } else {
|
|
|
|
|
- return eventSourceHash // can't fetch if don't know the framing range
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ case 'CHANGE_TIMEZONE':
|
|
|
|
|
+ return fetchSourcesByIds(
|
|
|
|
|
+ eventSources,
|
|
|
|
|
+ (action as any).sourceIds ?
|
|
|
|
|
+ arrayToHash((action as any).sourceIds) :
|
|
|
|
|
+ excludeStaticSources(eventSources),
|
|
|
|
|
+ dateProfile ? dateProfile.activeRange : null,
|
|
|
|
|
+ calendar
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
case 'RECEIVE_EVENTS':
|
|
case 'RECEIVE_EVENTS':
|
|
|
case 'RECEIVE_EVENT_ERROR':
|
|
case 'RECEIVE_EVENT_ERROR':
|
|
|
- return receiveResponse(eventSourceHash, action.sourceId, action.fetchId, action.fetchRange)
|
|
|
|
|
|
|
+ return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange)
|
|
|
|
|
|
|
|
case 'REMOVE_ALL_EVENT_SOURCES':
|
|
case 'REMOVE_ALL_EVENT_SOURCES':
|
|
|
return {}
|
|
return {}
|
|
|
|
|
|
|
|
default:
|
|
default:
|
|
|
- return eventSourceHash
|
|
|
|
|
|
|
+ return eventSources
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
let uid = 0
|
|
let uid = 0
|
|
|
|
|
|
|
|
-function addSources(eventSourceHash: EventSourceHash, sources: EventSource[], dateProfile: DateProfile | null, calendar: Calendar): EventSourceHash {
|
|
|
|
|
|
|
+
|
|
|
|
|
+function addSources(eventSourceHash: EventSourceHash, sources: EventSource[], fetchRange: DateRange | null, calendar: Calendar): EventSourceHash {
|
|
|
let hash: EventSourceHash = {}
|
|
let hash: EventSourceHash = {}
|
|
|
|
|
|
|
|
for (let source of sources) {
|
|
for (let source of sources) {
|
|
|
hash[source.sourceId] = source
|
|
hash[source.sourceId] = source
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (dateProfile) {
|
|
|
|
|
- hash = fetchDirtySources(hash, dateProfile, calendar)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ hash = fetchDirtySources(hash, fetchRange, calendar)
|
|
|
|
|
|
|
|
return assignTo({}, eventSourceHash, hash)
|
|
return assignTo({}, eventSourceHash, hash)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
function removeSource(eventSourceHash: EventSourceHash, sourceId: string): EventSourceHash {
|
|
function removeSource(eventSourceHash: EventSourceHash, sourceId: string): EventSourceHash {
|
|
|
return filterHash(eventSourceHash, function(eventSource: EventSource) {
|
|
return filterHash(eventSourceHash, function(eventSource: EventSource) {
|
|
|
return eventSource.sourceId !== sourceId
|
|
return eventSource.sourceId !== sourceId
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function fetchDirtySources(sourceHash: EventSourceHash, dateProfile: DateProfile, calendar: Calendar): EventSourceHash {
|
|
|
|
|
- let activeRange = dateProfile.activeRange
|
|
|
|
|
- let dirtySourceIds = []
|
|
|
|
|
|
|
|
|
|
|
|
+function fetchDirtySources(sourceHash: EventSourceHash, fetchRange: DateRange | null, calendar: Calendar): EventSourceHash {
|
|
|
|
|
+ return fetchSourcesByIds(
|
|
|
|
|
+ sourceHash,
|
|
|
|
|
+ filterHash(sourceHash, function(eventSource) {
|
|
|
|
|
+ return isSourceDirty(eventSource, fetchRange, calendar)
|
|
|
|
|
+ }),
|
|
|
|
|
+ fetchRange,
|
|
|
|
|
+ calendar
|
|
|
|
|
+ )
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- for (let sourceId in sourceHash) {
|
|
|
|
|
- let eventSource = sourceHash[sourceId]
|
|
|
|
|
|
|
|
|
|
- if (
|
|
|
|
|
- !calendar.opt('lazyFetching') ||
|
|
|
|
|
- !eventSource.fetchRange ||
|
|
|
|
|
- activeRange.start < eventSource.fetchRange.start ||
|
|
|
|
|
- activeRange.end > eventSource.fetchRange.end
|
|
|
|
|
- ) {
|
|
|
|
|
- dirtySourceIds.push(eventSource.sourceId)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+function isSourceDirty(eventSource: EventSource, fetchRange: DateRange | null, calendar: Calendar) {
|
|
|
|
|
|
|
|
- if (dirtySourceIds.length) {
|
|
|
|
|
- sourceHash = fetchSourcesByIds(sourceHash, dirtySourceIds, dateProfile, calendar)
|
|
|
|
|
|
|
+ if (!doesSourceNeedRange(eventSource)) {
|
|
|
|
|
+ return !eventSource.latestFetchId
|
|
|
|
|
+ } else if (fetchRange) {
|
|
|
|
|
+ return !calendar.opt('lazyFetching') ||
|
|
|
|
|
+ !eventSource.fetchRange ||
|
|
|
|
|
+ fetchRange.start < eventSource.fetchRange.start ||
|
|
|
|
|
+ fetchRange.end > eventSource.fetchRange.end
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return sourceHash
|
|
|
|
|
|
|
+ return false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
function fetchSourcesByIds(
|
|
function fetchSourcesByIds(
|
|
|
prevSources: EventSourceHash,
|
|
prevSources: EventSourceHash,
|
|
|
- sourceIds: string[] | null,
|
|
|
|
|
- dateProfile: DateProfile,
|
|
|
|
|
|
|
+ sourceIdHash: { [sourceId: string]: any },
|
|
|
|
|
+ fetchRange: DateRange | null,
|
|
|
calendar: Calendar
|
|
calendar: Calendar
|
|
|
): EventSourceHash {
|
|
): EventSourceHash {
|
|
|
- let sourceIdHash = sourceIds ? arrayToHash(sourceIds) : null
|
|
|
|
|
let nextSources: EventSourceHash = {}
|
|
let nextSources: EventSourceHash = {}
|
|
|
- let activeRange = dateProfile.activeRange
|
|
|
|
|
|
|
|
|
|
for (let sourceId in prevSources) {
|
|
for (let sourceId in prevSources) {
|
|
|
let source = prevSources[sourceId]
|
|
let source = prevSources[sourceId]
|
|
|
|
|
|
|
|
- if (!sourceIdHash || sourceIdHash[sourceId]) {
|
|
|
|
|
- nextSources[sourceId] = fetchSource(source, activeRange, calendar)
|
|
|
|
|
|
|
+ if (sourceIdHash[sourceId]) {
|
|
|
|
|
+ nextSources[sourceId] = fetchSource(source, fetchRange, calendar)
|
|
|
} else {
|
|
} else {
|
|
|
nextSources[sourceId] = source
|
|
nextSources[sourceId] = source
|
|
|
}
|
|
}
|
|
@@ -107,24 +113,16 @@ function fetchSourcesByIds(
|
|
|
return nextSources
|
|
return nextSources
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function fetchSource(eventSource: EventSource, range: DateRange, calendar: Calendar) {
|
|
|
|
|
- let sourceDef = getEventSourceDef(eventSource.sourceDefId)
|
|
|
|
|
|
|
|
|
|
- if (sourceDef.singleFetch && eventSource.fetchRange) {
|
|
|
|
|
- return eventSource
|
|
|
|
|
- } else {
|
|
|
|
|
- return fetchSourceAsync(eventSource, sourceDef, range, calendar)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function fetchSourceAsync(eventSource: EventSource, sourceDef: EventSourceDef, range: DateRange, calendar: Calendar) {
|
|
|
|
|
|
|
+function fetchSource(eventSource: EventSource, fetchRange: DateRange | null, calendar: Calendar) {
|
|
|
|
|
+ let sourceDef = getEventSourceDef(eventSource.sourceDefId)
|
|
|
let fetchId = String(uid++)
|
|
let fetchId = String(uid++)
|
|
|
|
|
|
|
|
sourceDef.fetch(
|
|
sourceDef.fetch(
|
|
|
{
|
|
{
|
|
|
eventSource,
|
|
eventSource,
|
|
|
calendar,
|
|
calendar,
|
|
|
- range
|
|
|
|
|
|
|
+ range: fetchRange
|
|
|
},
|
|
},
|
|
|
function(rawEvents) {
|
|
function(rawEvents) {
|
|
|
|
|
|
|
@@ -136,7 +134,7 @@ function fetchSourceAsync(eventSource: EventSource, sourceDef: EventSourceDef, r
|
|
|
type: 'RECEIVE_EVENTS',
|
|
type: 'RECEIVE_EVENTS',
|
|
|
sourceId: eventSource.sourceId,
|
|
sourceId: eventSource.sourceId,
|
|
|
fetchId,
|
|
fetchId,
|
|
|
- fetchRange: range,
|
|
|
|
|
|
|
+ fetchRange,
|
|
|
rawEvents
|
|
rawEvents
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
@@ -153,20 +151,19 @@ function fetchSourceAsync(eventSource: EventSource, sourceDef: EventSourceDef, r
|
|
|
type: 'RECEIVE_EVENT_ERROR',
|
|
type: 'RECEIVE_EVENT_ERROR',
|
|
|
sourceId: eventSource.sourceId,
|
|
sourceId: eventSource.sourceId,
|
|
|
fetchId,
|
|
fetchId,
|
|
|
- fetchRange: range,
|
|
|
|
|
|
|
+ fetchRange,
|
|
|
error
|
|
error
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- // TODO: if singleFetch, remove the meta at this point?
|
|
|
|
|
-
|
|
|
|
|
return assignTo({}, eventSource, {
|
|
return assignTo({}, eventSource, {
|
|
|
isFetching: true,
|
|
isFetching: true,
|
|
|
latestFetchId: fetchId
|
|
latestFetchId: fetchId
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
function receiveResponse(sourceHash: EventSourceHash, sourceId: string, fetchId: string, fetchRange: DateRange) {
|
|
function receiveResponse(sourceHash: EventSourceHash, sourceId: string, fetchId: string, fetchRange: DateRange) {
|
|
|
let eventSource: EventSource = sourceHash[sourceId]
|
|
let eventSource: EventSource = sourceHash[sourceId]
|
|
|
|
|
|
|
@@ -182,6 +179,7 @@ function receiveResponse(sourceHash: EventSourceHash, sourceId: string, fetchId:
|
|
|
return sourceHash
|
|
return sourceHash
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
function normalizeError(input: any): SimpleError {
|
|
function normalizeError(input: any): SimpleError {
|
|
|
if (typeof input === 'string') {
|
|
if (typeof input === 'string') {
|
|
|
return { message: input }
|
|
return { message: input }
|
|
@@ -189,3 +187,10 @@ function normalizeError(input: any): SimpleError {
|
|
|
return input || {}
|
|
return input || {}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+function excludeStaticSources(eventSources: EventSourceHash): EventSourceHash {
|
|
|
|
|
+ return filterHash(eventSources, function(eventSource) {
|
|
|
|
|
+ return doesSourceNeedRange(eventSource)
|
|
|
|
|
+ })
|
|
|
|
|
+}
|