object-array-utils
Advanced tools
+2
-1
@@ -77,2 +77,3 @@ export type PlainObject<T = unknown> = Record<string, T>; | ||
| declare function unique<T, K = T>(array: readonly T[], keyFn?: (item: T) => K): T[]; | ||
| export { areArraysEqual, arePlainObjectsEqual, areDataEqual, deepClonePlain, deepFreezePlain, differencePrimitives, repeat, pickProperties, hasProperty, hasProperties, isArraySubset, isArrayWhereEvery, isEmptyArray, isEmptyPlainObject, isNullOrUndefined, isPlainObject, isPlainObjectWhereEvery, isPlainObjectSubset, isPrimitive, isPrimitiveWrapper, range, omitProperties, removeArrayElement, removeArrayElementByIndex, removeArrayElements, toSortedObject, unboxPrimitiveWrapper, partitionProperties, unique }; | ||
| declare function makeCopyOnWriteObjectSetter<T extends PlainObject>(base: T): <K extends keyof T>(key: K, value: T[K]) => T; | ||
| export { areArraysEqual, arePlainObjectsEqual, areDataEqual, deepClonePlain, deepFreezePlain, differencePrimitives, repeat, pickProperties, hasProperty, hasProperties, isArraySubset, isArrayWhereEvery, isEmptyArray, isEmptyPlainObject, isNullOrUndefined, isPlainObject, isPlainObjectWhereEvery, isPlainObjectSubset, isPrimitive, isPrimitiveWrapper, range, omitProperties, removeArrayElement, removeArrayElementByIndex, removeArrayElements, toSortedObject, unboxPrimitiveWrapper, partitionProperties, unique, makeCopyOnWriteObjectSetter, }; |
+14
-1
@@ -433,2 +433,15 @@ function isPrimitive(v) { | ||
| } | ||
| export { areArraysEqual, arePlainObjectsEqual, areDataEqual, deepClonePlain, deepFreezePlain, differencePrimitives, repeat, pickProperties, hasProperty, hasProperties, isArraySubset, isArrayWhereEvery, isEmptyArray, isEmptyPlainObject, isNullOrUndefined, isPlainObject, isPlainObjectWhereEvery, isPlainObjectSubset, isPrimitive, isPrimitiveWrapper, range, omitProperties, removeArrayElement, removeArrayElementByIndex, removeArrayElements, toSortedObject, unboxPrimitiveWrapper, partitionProperties, unique }; | ||
| function makeCopyOnWriteObjectSetter(base) { | ||
| if (!isPlainObject(base)) | ||
| throw new Error('base must be a plain object'); | ||
| let draft = base; | ||
| return function set(key, value) { | ||
| if (Object.is(draft[key], value)) | ||
| return draft; | ||
| if (draft === base) | ||
| draft = { ...base }; | ||
| draft[key] = value; | ||
| return draft; | ||
| }; | ||
| } | ||
| export { areArraysEqual, arePlainObjectsEqual, areDataEqual, deepClonePlain, deepFreezePlain, differencePrimitives, repeat, pickProperties, hasProperty, hasProperties, isArraySubset, isArrayWhereEvery, isEmptyArray, isEmptyPlainObject, isNullOrUndefined, isPlainObject, isPlainObjectWhereEvery, isPlainObjectSubset, isPrimitive, isPrimitiveWrapper, range, omitProperties, removeArrayElement, removeArrayElementByIndex, removeArrayElements, toSortedObject, unboxPrimitiveWrapper, partitionProperties, unique, makeCopyOnWriteObjectSetter, }; |
+22
-1
| import { expect, test } from 'vitest'; | ||
| import { areArraysEqual, arePlainObjectsEqual, areDataEqual, deepClonePlain, deepFreezePlain, differencePrimitives, repeat, pickProperties, omitProperties, partitionProperties, hasProperties, isArrayWhereEvery, isEmptyArray, isEmptyPlainObject, isPlainObject, isPlainObjectWhereEvery, isPrimitive, isPrimitiveWrapper, unboxPrimitiveWrapper, range, removeArrayElement, removeArrayElementByIndex, removeArrayElements, toSortedObject, unique } from './index'; | ||
| import { areArraysEqual, arePlainObjectsEqual, areDataEqual, deepClonePlain, deepFreezePlain, differencePrimitives, repeat, pickProperties, omitProperties, partitionProperties, hasProperties, isArrayWhereEvery, isEmptyArray, isEmptyPlainObject, isPlainObject, isPlainObjectWhereEvery, isPrimitive, isPrimitiveWrapper, unboxPrimitiveWrapper, range, removeArrayElement, removeArrayElementByIndex, removeArrayElements, toSortedObject, unique, makeCopyOnWriteObjectSetter } from './index'; | ||
| test('areDataEqual', () => { | ||
@@ -236,1 +236,22 @@ const areNonPlainObjectsEqual = () => { throw new Error(); }; | ||
| }); | ||
| test('makeCopyOnWriteObjectSetter, copy-on-write semantics', () => { | ||
| const base = { a: 1, b: 2 }; | ||
| const set = makeCopyOnWriteObjectSetter(base); | ||
| const r0 = set('a', 1); | ||
| expect(r0).toBe(base); | ||
| const r1 = set('a', 42); | ||
| expect(r1).not.toBe(base); | ||
| expect(r1).toEqual({ a: 42, b: 2 }); | ||
| const r2 = set('b', 99); | ||
| expect(r2).toBe(r1); | ||
| expect(r2).toEqual({ a: 42, b: 99 }); | ||
| const r3 = set('b', 99); | ||
| expect(r3).toBe(r2); | ||
| }); | ||
| test('makeCopyOnWriteObjectSetter, shallow clone only', () => { | ||
| const base = { a: { x: 1 }, b: 2 }; | ||
| const set = makeCopyOnWriteObjectSetter(base); | ||
| const updated = set('b', 3); | ||
| expect(updated).not.toBe(base); | ||
| expect(updated.a).toBe(base.a); | ||
| }); |
+1
-1
| { | ||
| "name": "object-array-utils", | ||
| "version": "5.0.0", | ||
| "version": "5.1.0", | ||
| "description": "Utilities for working with arrays and objects", | ||
@@ -5,0 +5,0 @@ "funding": "https://github.com/mathieuprog/object-array-utils?sponsor=1", |
+16
-0
@@ -173,2 +173,18 @@ # `object-array-utils` | ||
| ) // [{ name: 'John', age: 27 }, { name: 'James', age: 42 }] | ||
| import { makeCopyOnWriteObjectSetter } from 'object-array-utils'; | ||
| const base = { a: 1, b: 2 }; | ||
| const set = makeCopyOnWriteObjectSetter(base); | ||
| // No-op: same value ⇒ original reference | ||
| set('a', 1) === base; // true | ||
| // First real update ⇒ shallow-clone | ||
| const draft = set('a', 42); | ||
| draft // { a: 42, b: 2 } | ||
| base // { a: 1, b: 2 } | ||
| // Further updates mutate the same draft | ||
| set('b', 99) === draft; // true | ||
| ``` | ||
@@ -175,0 +191,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
54322
3.29%784
4.67%208
8.33%0
-100%