Created
February 22, 2017 21:48
-
-
Save micahnz/70c46956b9ad27b1dda81d87c0dc9a1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
import semver from 'semver'; | |
// | |
export function createVersionedReducer() { | |
const ranges = []; | |
const map = {}; | |
// | |
function versionedReducer(state, action) { | |
const { meta } = action; | |
// | |
if (meta === undefined || meta.version === undefined) { | |
throw new Error('Expected versioned action'); | |
} | |
// | |
const version = semver.valid(meta.version); | |
if (version === null) { | |
throw new Error(`"${meta.version}" is not a valid semantic version"`); | |
} | |
// try direct version match | |
const vMatch = ranges.filter((r) => { | |
const v = semver.valid(r); | |
if (v) return semver.eq(version, v); | |
return false; | |
}); | |
// use direct match over anything else | |
if (vMatch.length === 1) { | |
return map[vMatch[0]](state, action); | |
} | |
// try range match | |
const rMatch = ranges.filter((r) => { | |
return semver.satisfies(version, r); | |
}); | |
if (rMatch.length > 1) { | |
throw new Error(`more than one reducer for semantic version "${version}" ${rMatch}`); | |
} else if (rMatch.length > 0) { | |
return map[rMatch[0]](state, action); | |
} else { | |
throw new Error(`no reducer for semantic version "${version}"`); | |
} | |
} | |
// | |
versionedReducer.addVersion = (userRange, fn) => { | |
const range = semver.validRange(userRange); | |
if (range === null) { | |
throw new Error(`"${userRange}" is not a valid semantic version range"`); | |
} | |
if (ranges.indexOf(range) !== -1) { | |
throw new Error(`a reducer with the semantic version range "${range}" already exists"`); | |
} | |
// | |
ranges.push(range); | |
map[range] = fn; | |
// | |
return versionedReducer; | |
}; | |
// | |
return versionedReducer; | |
} | |
// | |
export default createVersionedReducer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment