Skip to content

Commit

Permalink
🚧 Props nav
Browse files Browse the repository at this point in the history
  • Loading branch information
nlepage committed Jul 19, 2019
1 parent c02f125 commit 30d41f0
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 9 deletions.
8 changes: 6 additions & 2 deletions packages/immutadot/src/nav2/finalNav.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
const update = updater => value => updater(value)

const get = () => value => value

const unset = () => undefined

export const finalNav = operation => {
switch (operation) {
case 'update': return update
case 'get': return null
case 'unset': return null
case 'get': return get
case 'unset': return unset
}
throw TypeError(`Unknown navigator operation ${operation}`)
}
Expand Down
2 changes: 2 additions & 0 deletions packages/immutadot/src/nav2/nav.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { finalNav } from './finalNav'
import { propNav } from './propNav'
import { propsNav } from './propsNav'

const toNav = ([type, params]) => {
switch (type) {
case 'prop': return propNav(params)
case 'props': return propsNav(params)
}
throw TypeError(`Unknown navigator type ${type}`)
}
Expand Down
8 changes: 8 additions & 0 deletions packages/immutadot/src/nav2/nav.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,12 @@ describe('nav.nav', () => {
return output
},
))

it('should get a nested prop', () => {
const input = {
nested: { prop: 'foo' },
other: { prop: 'baz' },
}
expect(nav([['prop', 'nested'], ['prop', 'prop']])('get')()(input)).toEqual('foo')
})
})
8 changes: 7 additions & 1 deletion packages/immutadot/src/nav2/objectNav.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { isNil } from 'util/lang'

export const copy = value => isNil(value) ? {} : { ...value }
export const onCopy = (cb, force = false) => value => {
const nil = isNil(value)
if (nil && !force) return value
const newValue = nil ? {} : { ...value }
cb(newValue, value)
return newValue
}
27 changes: 21 additions & 6 deletions packages/immutadot/src/nav2/propNav.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
import { copy } from './objectNav'
import { isNil } from 'util/lang'
import { onCopy } from './objectNav'

const update = (key, next) => updater => {
const nextUpdater = next(updater)
return value => {
const newValue = copy(value)
return onCopy((newValue, value) => {
newValue[key] = nextUpdater(isNil(value) ? undefined : value[key])
return newValue
})
}

const get = (key, next) => () => {
const nextGetter = next()
return value => nextGetter(isNil(value) ? undefined : value[key])
}

const unset = (key, next) => () => {
const nextUnsetter = next()
if (nextUnsetter) {
return onCopy((newValue, value) => {
newValue[key] = nextUnsetter(isNil(value) ? undefined : value[key])
})
}
return onCopy(newValue => {
delete newValue[key]
})
}

export const propNav = key => next => operation => {
switch (operation) {
case 'update': return update(key, next(operation))
case 'get': return null
case 'unset': return null
case 'get': return get(key, next(operation))
case 'unset': return unset(key, next(operation))
}
throw TypeError(`Unknown navigator operation ${operation}`)
}

0 comments on commit 30d41f0

Please sign in to comment.