Skip to content

Commit

Permalink
feat: List .update method accepts onMerge function for custom deep me…
Browse files Browse the repository at this point in the history
…rge cases.
  • Loading branch information
andreidmt committed Apr 27, 2020
1 parent c21827e commit 797b7e1
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 8 deletions.
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ const buildList = ({
})
},

update: (id, data, { isLocal = false, ...options } = {}) => {
update: (id, data, { isLocal = false, onMerge, ...options } = {}) => {
if (isLocal === false && typeof update !== "function") {
throw new TypeError(
`ReduxList: "${name}"."update" must be a function, got "${typeof update}"`
Expand All @@ -211,6 +211,7 @@ const buildList = ({
payload: {
listName: name,
item: { id, ...data },
onMerge,
onChange,
},
})
Expand All @@ -226,11 +227,12 @@ const buildList = ({
api: update,
hasDispatchStart,
hasDispatchEnd,
onMerge,
onChange,
}),

// queue calls fn(...args)
args: [id, data, { isLocal, ...options }],
args: [id, data, options],
})
},

Expand Down
2 changes: 2 additions & 0 deletions src/update/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const updateAction = ({
api,
hasDispatchStart,
hasDispatchEnd,
onMerge,
onChange,
}) => (id, data, ...rest) => {
if (isEmpty(id)) {
Expand Down Expand Up @@ -58,6 +59,7 @@ export const updateAction = ({
...result,
id: hasKey("id")(result) ? result.id : id,
},
onMerge,
onChange,
},
})
Expand Down
6 changes: 3 additions & 3 deletions src/update/update.reducers.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
const debug = require("debug")("ReduxList:UpdateReducers")

import { intersect, i } from "@mutant-ws/m"
import { intersect, i, is } from "@mutant-ws/m"

export const startReducer = (state, { id, data }) => ({
...state,
updating: [{ id, data }],
})

export const endReducer = (state, { item, onChange = i }) => {
export const endReducer = (state, { item, onMerge, onChange = i }) => {
return {
...state,
items: onChange(
intersect(
(a, b) => a.id === b.id,
(a, b) => ({ ...a, ...b })
is(onMerge) ? onMerge : (a, b) => ({ ...a, ...b })
)(state.items, [item])
),

Expand Down
46 changes: 43 additions & 3 deletions src/update/update.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from "tape"
import { createStore, combineReducers } from "redux"
import { map, is } from "@mutant-ws/m"
import { map, concat, is } from "@mutant-ws/m"

import { buildList } from ".."

Expand All @@ -10,7 +10,7 @@ test("Update", async t => {
name: "UPDATE_TODOS",
read: () => [
{ id: 1, name: "lorem ipsum" },
{ id: 2, name: "foo bar" },
{ id: 2, name: "foo bar", items: [{ id: 1, label: "item 1" }] },
],
update: (id, data) => ({
id,
Expand Down Expand Up @@ -47,11 +47,17 @@ test("Update", async t => {
items(),
[
{ id: 1, name: "lorem ipsum", onChange: 2 },
{ id: 2, name: "Updated foo", onChange: 2 },
{
id: 2,
name: "Updated foo",
items: [{ id: 1, label: "item 1" }],
onChange: 2,
},
],
"element should be updated in items array"
)
}

{
const { result } = await todos.update(
2,
Expand All @@ -66,5 +72,39 @@ test("Update", async t => {
)
}

{
await todos.update(
2,
{ name: "Updated foo", items: [{ id: 2 }] },
{
onMerge: (
{ items: aItems = [], ...aRest },
{ items: bItems = [], ...bRest }
) => {
return {
...aRest,
...bRest,
items: concat(aItems)(bItems),
}
},
}
)
const { items } = todos.selector(store.getState())

t.deepEquals(
items(),
[
{ id: 1, name: "lorem ipsum", onChange: 4 },
{
id: 2,
name: "Updated foo",
items: [{ id: 1, label: "item 1" }, { id: 2 }],
onChange: 4,
},
],
"element should be updated in items array via custom onMerge function"
)
}

t.end()
})

0 comments on commit 797b7e1

Please sign in to comment.