Skip to content

Commit

Permalink
Add modifyWithImmer (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
AkhilXavier95 authored Nov 1, 2023
1 parent b19a6a6 commit 917d672
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 16 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"husky": "^7.0.4",
"i18next": "22.5.1",
"i18next-browser-languagedetector": "^7.1.0",
"immer": "^10.0.3",
"jest": "27.5.1",
"js-logger": "^1.6.1",
"lint-staged": "^12.3.7",
Expand Down
10 changes: 8 additions & 2 deletions src/general.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { produce } from "immer";

import {
complement,
curry,
Expand All @@ -13,7 +15,7 @@ import {
* @param {T} func
* @returns {T}
*/
export const nullSafe = (func) =>
export const nullSafe = func =>
// @ts-ignore
curryN(func.length, (...args) => {
const dataArg = args[func.length - 1];
Expand All @@ -23,7 +25,7 @@ export const nullSafe = (func) =>

export const noop = () => {};

export const toLabelAndValue = (string) => ({ label: string, value: string });
export const toLabelAndValue = string => ({ label: string, value: string });

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

export const notEqualsDeep = /*#__PURE__*/ complement(equals);
export const isNotEqualDeep = notEqualsDeep;

export const modifyWithImmer = /*#__PURE__*/ curry((modifier, data) =>
produce(data, modifier)
);
24 changes: 10 additions & 14 deletions src/objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const transformObjectDeep = (
}

if (Array.isArray(object)) {
return object.map((obj) =>
return object.map(obj =>
transformObjectDeep(obj, keyValueTransformer, objectPreProcessor)
);
} else if (object === null || typeof object !== "object") {
Expand All @@ -45,33 +45,29 @@ export const transformObjectDeep = (
);
};

export const keysToCamelCase = (object) =>
export const keysToCamelCase = object =>
transformObjectDeep(object, (key, value) => [snakeToCamelCase(key), value]);

export const keysToSnakeCase = (object) =>
export const keysToSnakeCase = object =>
transformObjectDeep(object, (key, value) => [camelToSnakeCase(key), value]);

export const serializeKeysToSnakeCase = (object) =>
export const serializeKeysToSnakeCase = object =>
transformObjectDeep(
object,
(key, value) => [camelToSnakeCase(key), value],
(object) =>
typeof object?.toJSON === "function" ? object.toJSON() : object
object => (typeof object?.toJSON === "function" ? object.toJSON() : object)
);

export const preprocessForSerialization = (object) =>
export const preprocessForSerialization = object =>
transformObjectDeep(
object,
(key, value) => [key, value],
(object) =>
typeof object?.toJSON === "function" ? object.toJSON() : object
object => (typeof object?.toJSON === "function" ? object.toJSON() : object)
);

export const deepFreezeObject = (object) => {
export const deepFreezeObject = object => {
if (object && typeof object === "object" && !Object.isFrozen(object)) {
Object.keys(object).forEach((property) =>
deepFreezeObject(object[property])
);
Object.keys(object).forEach(property => deepFreezeObject(object[property]));
Object.freeze(object);
}

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

export const filterNonNull = (object) =>
export const filterNonNull = object =>
Object.fromEntries(
Object.entries(object)
.filter(([, v]) => !isNil(v))
Expand Down
18 changes: 18 additions & 0 deletions tests/general.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
randomPick,
toLabelAndValue,
nullSafe,
modifyWithImmer,
} from "src/general";

describe("General functions", () => {
Expand Down Expand Up @@ -137,4 +138,21 @@ describe("General functions", () => {
expect(isPresent(undefined)).toBe(false);
expect(isPresent(null)).toBe(false);
});

test("modifyWithImmer() should not mutate the original value", () => {
const state = [{ name: "Oliver" }, { name: "Eve" }];
const nextState = modifyWithImmer(data => {
data[0].name = "Oliver smith";
})(state);
expect(nextState).not.toBe(state);
});

test("modifyWithImmer() should work on objects", () => {
const state = { name: "Oliver" };
expect(
modifyWithImmer(data => {
data.name = "Oliver smith";
})(state)
).toStrictEqual({ name: "Oliver smith" });
});
});
9 changes: 9 additions & 0 deletions typeTemplates/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,12 @@ export function nullSafe<T extends Function>(

export function isNotPresent(object: any): boolean;
export function isPresent(object: any): boolean;

export function modifyWithImmer<T>(
modifier: (draft: Draft<T>) => void,
data: T
): T;

export function modifyWithImmer<T>(
modifier: (draft: Draft<T>) => void
): (data: T) => T;
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8701,6 +8701,11 @@ ignore@^5.2.0:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==

immer@^10.0.3:
version "10.0.3"
resolved "https://registry.yarnpkg.com/immer/-/immer-10.0.3.tgz#a8de42065e964aa3edf6afc282dfc7f7f34ae3c9"
integrity sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==

immutable@^4.0.0:
version "4.2.4"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.4.tgz#83260d50889526b4b531a5e293709a77f7c55a2a"
Expand Down

0 comments on commit 917d672

Please sign in to comment.