Skip to content

Commit 917d672

Browse files
Add modifyWithImmer (#14)
1 parent b19a6a6 commit 917d672

6 files changed

Lines changed: 51 additions & 16 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"husky": "^7.0.4",
101101
"i18next": "22.5.1",
102102
"i18next-browser-languagedetector": "^7.1.0",
103+
"immer": "^10.0.3",
103104
"jest": "27.5.1",
104105
"js-logger": "^1.6.1",
105106
"lint-staged": "^12.3.7",

src/general.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { produce } from "immer";
2+
13
import {
24
complement,
35
curry,
@@ -13,7 +15,7 @@ import {
1315
* @param {T} func
1416
* @returns {T}
1517
*/
16-
export const nullSafe = (func) =>
18+
export const nullSafe = func =>
1719
// @ts-ignore
1820
curryN(func.length, (...args) => {
1921
const dataArg = args[func.length - 1];
@@ -23,7 +25,7 @@ export const nullSafe = (func) =>
2325

2426
export const noop = () => {};
2527

26-
export const toLabelAndValue = (string) => ({ label: string, value: string });
28+
export const toLabelAndValue = string => ({ label: string, value: string });
2729

2830
// eslint-disable-next-line default-param-last
2931
export const getRandomInt = (a = Number.MAX_SAFE_INTEGER, b) => {
@@ -57,3 +59,7 @@ export const isPresent = /*#__PURE__*/ complement(isNotPresent);
5759

5860
export const notEqualsDeep = /*#__PURE__*/ complement(equals);
5961
export const isNotEqualDeep = notEqualsDeep;
62+
63+
export const modifyWithImmer = /*#__PURE__*/ curry((modifier, data) =>
64+
produce(data, modifier)
65+
);

src/objects.js

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const transformObjectDeep = (
2828
}
2929

3030
if (Array.isArray(object)) {
31-
return object.map((obj) =>
31+
return object.map(obj =>
3232
transformObjectDeep(obj, keyValueTransformer, objectPreProcessor)
3333
);
3434
} else if (object === null || typeof object !== "object") {
@@ -45,33 +45,29 @@ export const transformObjectDeep = (
4545
);
4646
};
4747

48-
export const keysToCamelCase = (object) =>
48+
export const keysToCamelCase = object =>
4949
transformObjectDeep(object, (key, value) => [snakeToCamelCase(key), value]);
5050

51-
export const keysToSnakeCase = (object) =>
51+
export const keysToSnakeCase = object =>
5252
transformObjectDeep(object, (key, value) => [camelToSnakeCase(key), value]);
5353

54-
export const serializeKeysToSnakeCase = (object) =>
54+
export const serializeKeysToSnakeCase = object =>
5555
transformObjectDeep(
5656
object,
5757
(key, value) => [camelToSnakeCase(key), value],
58-
(object) =>
59-
typeof object?.toJSON === "function" ? object.toJSON() : object
58+
object => (typeof object?.toJSON === "function" ? object.toJSON() : object)
6059
);
6160

62-
export const preprocessForSerialization = (object) =>
61+
export const preprocessForSerialization = object =>
6362
transformObjectDeep(
6463
object,
6564
(key, value) => [key, value],
66-
(object) =>
67-
typeof object?.toJSON === "function" ? object.toJSON() : object
65+
object => (typeof object?.toJSON === "function" ? object.toJSON() : object)
6866
);
6967

70-
export const deepFreezeObject = (object) => {
68+
export const deepFreezeObject = object => {
7169
if (object && typeof object === "object" && !Object.isFrozen(object)) {
72-
Object.keys(object).forEach((property) =>
73-
deepFreezeObject(object[property])
74-
);
70+
Object.keys(object).forEach(property => deepFreezeObject(object[property]));
7571
Object.freeze(object);
7672
}
7773

@@ -82,7 +78,7 @@ export const matches = /*#__PURE__*/ curry((pattern, object) =>
8278
matchesImpl(pattern, object)
8379
);
8480

85-
export const filterNonNull = (object) =>
81+
export const filterNonNull = object =>
8682
Object.fromEntries(
8783
Object.entries(object)
8884
.filter(([, v]) => !isNil(v))

tests/general.spec.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
randomPick,
1313
toLabelAndValue,
1414
nullSafe,
15+
modifyWithImmer,
1516
} from "src/general";
1617

1718
describe("General functions", () => {
@@ -137,4 +138,21 @@ describe("General functions", () => {
137138
expect(isPresent(undefined)).toBe(false);
138139
expect(isPresent(null)).toBe(false);
139140
});
141+
142+
test("modifyWithImmer() should not mutate the original value", () => {
143+
const state = [{ name: "Oliver" }, { name: "Eve" }];
144+
const nextState = modifyWithImmer(data => {
145+
data[0].name = "Oliver smith";
146+
})(state);
147+
expect(nextState).not.toBe(state);
148+
});
149+
150+
test("modifyWithImmer() should work on objects", () => {
151+
const state = { name: "Oliver" };
152+
expect(
153+
modifyWithImmer(data => {
154+
data.name = "Oliver smith";
155+
})(state)
156+
).toStrictEqual({ name: "Oliver smith" });
157+
});
140158
});

typeTemplates/index.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,12 @@ export function nullSafe<T extends Function>(
341341

342342
export function isNotPresent(object: any): boolean;
343343
export function isPresent(object: any): boolean;
344+
345+
export function modifyWithImmer<T>(
346+
modifier: (draft: Draft<T>) => void,
347+
data: T
348+
): T;
349+
350+
export function modifyWithImmer<T>(
351+
modifier: (draft: Draft<T>) => void
352+
): (data: T) => T;

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8701,6 +8701,11 @@ ignore@^5.2.0:
87018701
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
87028702
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
87038703

8704+
immer@^10.0.3:
8705+
version "10.0.3"
8706+
resolved "https://registry.yarnpkg.com/immer/-/immer-10.0.3.tgz#a8de42065e964aa3edf6afc282dfc7f7f34ae3c9"
8707+
integrity sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==
8708+
87048709
immutable@^4.0.0:
87058710
version "4.2.4"
87068711
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.4.tgz#83260d50889526b4b531a5e293709a77f7c55a2a"

0 commit comments

Comments
 (0)