Skip to content

Commit

Permalink
Add inherited to all methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Mar 13, 2022
1 parent 350815b commit c175dfa
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 55 deletions.
14 changes: 9 additions & 5 deletions src/config/normalize/lib/wild_wild_path/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@ export const list = function (
export const get = function (
target,
query,
{ childFirst, sort, classes } = {},
{ childFirst, sort, classes, inherited } = {},
) {
const entry = find(target, query, { childFirst, sort, classes })
const entry = find(target, query, { childFirst, sort, classes, inherited })
return entry === undefined ? undefined : entry.value
}

// Check if a property is not missing according to a query
export const has = function (target, query, { classes } = {}) {
export const has = function (target, query, { classes, inherited } = {}) {
return (
find(target, query, { childFirst: false, sort: false, classes }) !==
undefined
find(target, query, {
childFirst: false,
sort: false,
classes,
inherited,
}) !== undefined
)
}

Expand Down
12 changes: 6 additions & 6 deletions src/config/normalize/lib/wild_wild_path/remove.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ import { validateClasses, reduceParents, setValue } from './set.js'
export const remove = function (
target,
query,
{ classes = false, mutate = false } = {},
{ mutate = false, classes, inherited } = {},
) {
validateClasses(classes, mutate)
const setFunc = removeAnyEntry.bind(undefined, { classes, mutate })
return reduceParents({ target, query, setFunc, classes })
const setFunc = removeAnyEntry.bind(undefined, { mutate, classes })
return reduceParents({ target, query, setFunc, classes, inherited })
}

// eslint-disable-next-line max-params
const removeAnyEntry = function ({ classes, mutate }, target, path, index) {
const removeAnyEntry = function ({ mutate, classes }, target, path, index) {
return path.length === 0
? undefined
: removeEntry({ classes, mutate, target, path, index })
: removeEntry({ mutate, classes, target, path, index })
}

const removeEntry = function ({ classes, mutate, target, path, index }) {
const removeEntry = function ({ mutate, classes, target, path, index }) {
const prop = path[index]

if (handleMissingValue(target, prop, classes).missing) {
Expand Down
19 changes: 13 additions & 6 deletions src/config/normalize/lib/wild_wild_path/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ export const set = function (
target,
query,
value,
{ classes = false, mutate = false } = {},
{ mutate = false, classes, inherited } = {},
) {
validateClasses(classes, mutate)
const setFunc = setEntry.bind(undefined, { value, classes, mutate })
return reduceParents({ target, query, setFunc, classes })
const setFunc = setEntry.bind(undefined, { value, mutate, classes })
return reduceParents({ target, query, setFunc, classes, inherited })
}

// Class instances are not clonable. Therefore, they require `mutate`.
Expand All @@ -29,11 +29,18 @@ export const validateClasses = function (classes, mutate) {
}

// Modify a target object multiple times for each matched property.
export const reduceParents = function ({ target, query, setFunc, classes }) {
export const reduceParents = function ({
target,
query,
setFunc,
classes,
inherited,
}) {
const entries = list(target, query, {
childFirst: false,
sort: false,
classes,
inherited,
})
return entries
.filter(hasNoParentSet)
Expand All @@ -50,7 +57,7 @@ const hasNoParentSet = function ({ path: pathA }, indexA, entries) {

// Use positional arguments for performance
// eslint-disable-next-line max-params
const setEntry = function ({ value, classes, mutate }, target, path, index) {
const setEntry = function ({ value, mutate, classes }, target, path, index) {
if (index === path.length) {
return value
}
Expand All @@ -59,7 +66,7 @@ const setEntry = function ({ value, classes, mutate }, target, path, index) {
const { value: defaultedTarget } = handleMissingValue(target, prop, classes)
const childTarget = defaultedTarget[prop]
const childValue = setEntry(
{ value, classes, mutate },
{ value, mutate, classes },
childTarget,
path,
index + 1,
Expand Down
9 changes: 7 additions & 2 deletions src/config/normalize/lib/wild_wild_path_utils/find.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ export const find = function (
target,
query,
condition,
{ childFirst, sort, classes } = {},
{ childFirst, sort, classes, inherited } = {},
) {
// eslint-disable-next-line fp/no-loops
for (const entry of iterate(target, query, { childFirst, sort, classes })) {
for (const entry of iterate(target, query, {
childFirst,
sort,
classes,
inherited,
})) {
// eslint-disable-next-line max-depth
if (!entry.missing && condition(entry)) {
return entry
Expand Down
69 changes: 38 additions & 31 deletions src/config/normalize/lib/wild_wild_path_utils/include.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ import { set, remove, list } from '../wild_wild_path/main.js'
import { isParentPath } from '../wild_wild_path_parser/main.js'

// Returns an object with only the properties being queried.
export const pick = function (target, query, { sort, classes } = {}) {
return reduceParents(pickEntry.bind(undefined, classes), returnTrue, {
target,
newTarget: {},
query,
sort,
classes,
})
export const pick = function (
target,
query,
{ sort, classes, inherited } = {},
) {
return reduceParents(
pickEntry.bind(undefined, { classes, inherited }),
returnTrue,
{ target, newTarget: {}, query, sort, classes, inherited },
)
}

const returnTrue = function () {
Expand All @@ -22,19 +24,21 @@ export const include = function (
target,
query,
condition,
{ sort, classes } = {},
{ sort, classes, inherited } = {},
) {
return reduceParents(pickEntry.bind(undefined, classes), condition, {
target,
newTarget: {},
query,
sort,
classes,
})
return reduceParents(
pickEntry.bind(undefined, { classes, inherited }),
condition,
{ target, newTarget: {}, query, sort, classes, inherited },
)
}

const pickEntry = function (classes, newTarget, { path, value }) {
return set(newTarget, path, value, { classes, mutate: true })
const pickEntry = function (
{ classes, inherited },
newTarget,
{ path, value },
) {
return set(newTarget, path, value, { mutate: true, classes, inherited })
}

// Remove values matching a query
Expand All @@ -43,32 +47,35 @@ export const exclude = function (
target,
query,
condition,
{ classes, mutate } = {},
{ mutate, classes, inherited } = {},
) {
return reduceParents(
excludeEntry.bind(undefined, { classes, mutate }),
excludeEntry.bind(undefined, { mutate, classes, inherited }),
condition,
{
target,
newTarget: target,
query,
sort: false,
classes,
},
{ target, newTarget: target, query, sort: false, classes, inherited },
)
}

const excludeEntry = function ({ classes, mutate }, newTarget, { path }) {
return remove(newTarget, path, { classes, mutate })
const excludeEntry = function (
{ mutate, classes, inherited },
newTarget,
{ path },
) {
return remove(newTarget, path, { mutate, classes, inherited })
}

// Modify a target object multiple times for each matched property.
const reduceParents = function (
setFunc,
condition,
{ target, newTarget, query, sort, classes },
{ target, newTarget, query, sort, classes, inherited },
) {
const entries = list(target, query, { childFirst: false, sort, classes })
const entries = list(target, query, {
childFirst: false,
sort,
classes,
inherited,
})
return entries
.filter((entry) => shouldUseEntry(entry, target, condition))
.filter(hasNoParentSet)
Expand Down
17 changes: 12 additions & 5 deletions src/config/normalize/lib/wild_wild_path_utils/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,21 @@ import { list, get, set } from '../wild_wild_path/main.js'
// - When needed, this can also be done by the consumer logic
// - This also avoids infinite recursion
// eslint-disable-next-line max-params
export const map = function (target, query, mapFunc, { classes, mutate } = {}) {
export const map = function (
target,
query,
mapFunc,
{ mutate, classes, inherited } = {},
) {
const entries = list(target, query, {
childFirst: true,
sort: false,
classes,
inherited,
})
return entries.reduce(
(targetA, entry) =>
mapEntry({ mapFunc, target: targetA, entry, classes, mutate }),
mapEntry({ mapFunc, target: targetA, entry, mutate, classes, inherited }),
target,
)
}
Expand All @@ -30,12 +36,13 @@ const mapEntry = function ({
mapFunc,
target,
entry: { path, query, missing },
classes,
mutate,
classes,
inherited,
}) {
const value = get(target, path, { classes })
const value = get(target, path, { classes, inherited })
const mappedValue = mapFunc({ path, query, value, missing })
return value === mappedValue
? target
: set(target, path, mappedValue, { classes, mutate })
: set(target, path, mappedValue, { mutate, classes, inherited })
}

0 comments on commit c175dfa

Please sign in to comment.