proxy-compare
Advanced tools
Comparing version 2.6.0 to 3.0.0
{ | ||
"name": "proxy-compare", | ||
"description": "Compare two objects using accessed properties with Proxy", | ||
"version": "2.6.0", | ||
"version": "3.0.0", | ||
"type": "module", | ||
"author": "Daishi Kato", | ||
@@ -11,13 +12,15 @@ "repository": { | ||
"source": "./src/index.ts", | ||
"main": "./dist/index.umd.js", | ||
"module": "./dist/index.modern.js", | ||
"react-native": "./dist/index.modern.js", | ||
"types": "./dist/src/index.d.ts", | ||
"main": "./dist/index.js", | ||
"types": "./dist/index.d.ts", | ||
"exports": { | ||
"./package.json": "./package.json", | ||
".": { | ||
"types": "./dist/src/index.d.ts", | ||
"module": "./dist/index.modern.js", | ||
"import": "./dist/index.modern.mjs", | ||
"default": "./dist/index.umd.js" | ||
"require": { | ||
"types": "./dist/cjs/index.d.ts", | ||
"default": "./dist/cjs/index.js" | ||
}, | ||
"default": { | ||
"types": "./dist/index.d.ts", | ||
"default": "./dist/index.js" | ||
} | ||
} | ||
@@ -30,14 +33,14 @@ }, | ||
], | ||
"packageManager": "pnpm@8.15.0", | ||
"scripts": { | ||
"compile": "microbundle build -f modern,umd", | ||
"postcompile": "cp dist/index.modern.mjs dist/index.modern.js && cp dist/index.modern.mjs.map dist/index.modern.js.map", | ||
"test": "run-s eslint tsc-test jest", | ||
"eslint": "eslint --ext .js,.ts --ignore-pattern dist .", | ||
"jest": "jest", | ||
"tsc-test": "tsc --project . --noEmit", | ||
"apidoc": "documentation readme src --section API --markdown-toc false --parse-extension ts" | ||
"compile": "rm -rf dist && pnpm run '/^compile:.*/'", | ||
"compile:esm": "tsc -p tsconfig.esm.json", | ||
"compile:cjs": "tsc -p tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json", | ||
"test": "pnpm run '/^test:.*/'", | ||
"test:format": "prettier -c .", | ||
"test:lint": "eslint .", | ||
"test:types": "tsc -p . --noEmit", | ||
"test:spec": "vitest run", | ||
"apidoc": "documentation readme src/index.ts --section API --markdown-toc false --parse-extension ts --require-extension ts" | ||
}, | ||
"jest": { | ||
"preset": "ts-jest/presets/js-with-ts" | ||
}, | ||
"keywords": [ | ||
@@ -51,17 +54,20 @@ "proxy", | ||
"license": "MIT", | ||
"dependencies": {}, | ||
"prettier": { | ||
"singleQuote": true | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^29.5.11", | ||
"@typescript-eslint/eslint-plugin": "^6.18.1", | ||
"@typescript-eslint/parser": "^6.18.1", | ||
"documentation": "^14.0.2", | ||
"eslint": "^8.56.0", | ||
"eslint-config-airbnb-base": "^15.0.0", | ||
"@types/node": "^20.12.7", | ||
"@typescript-eslint/eslint-plugin": "^7.7.1", | ||
"@typescript-eslint/parser": "^7.7.1", | ||
"documentation": "^14.0.3", | ||
"eslint": "^8.57.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-import-resolver-typescript": "^3.6.1", | ||
"eslint-plugin-import": "^2.29.1", | ||
"jest": "^29.7.0", | ||
"microbundle": "^0.15.1", | ||
"npm-run-all": "^4.1.5", | ||
"ts-jest": "^29.1.1", | ||
"typescript": "^5.3.3" | ||
"prettier": "^3.2.5", | ||
"ts-expect": "^1.3.0", | ||
"typescript": "^5.4.5", | ||
"vite": "^5.2.10", | ||
"vitest": "^1.5.2" | ||
} | ||
} |
@@ -67,2 +67,3 @@ # proxy-compare | ||
* `proxyCache` **[WeakMap](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)<[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), unknown>?** WeakMap that will help keep referential identity for proxies. | ||
* `targetCache` **[WeakMap](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)<[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), any>?**  | ||
@@ -106,2 +107,3 @@ #### Examples | ||
and to avoid infinite loop with circular structures. | ||
* `isEqual` **function (a: any, b: any): [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** (optional, default `Object.is`) | ||
@@ -108,0 +110,0 @@ #### Examples |
102
src/index.ts
@@ -0,1 +1,3 @@ | ||
/* eslint @typescript-eslint/no-explicit-any: off */ | ||
// symbols | ||
@@ -19,6 +21,4 @@ const TRACK_MEMO_SYMBOL = Symbol(); | ||
// function to create a new bare proxy | ||
let newProxy = <T extends object>( | ||
target: T, | ||
handler: ProxyHandler<T>, | ||
) => new Proxy(target, handler); | ||
let newProxy = <T extends object>(target: T, handler: ProxyHandler<T>) => | ||
new Proxy(target, handler); | ||
@@ -31,13 +31,11 @@ // get object prototype | ||
// check if obj is a plain object or an array | ||
const isObjectToTrack = <T>(obj: T): obj is T extends object ? T : never => ( | ||
obj && (objectsToTrack.has(obj as unknown as object) | ||
? objectsToTrack.get(obj as unknown as object) as boolean | ||
: (getProto(obj) === Object.prototype || getProto(obj) === Array.prototype) | ||
) | ||
); | ||
const isObjectToTrack = <T>(obj: T): obj is T extends object ? T : never => | ||
obj && | ||
(objectsToTrack.has(obj as unknown as object) | ||
? (objectsToTrack.get(obj as unknown as object) as boolean) | ||
: getProto(obj) === Object.prototype || getProto(obj) === Array.prototype); | ||
// check if it is object | ||
const isObject = (x: unknown): x is object => ( | ||
typeof x === 'object' && x !== null | ||
); | ||
const isObject = (x: unknown): x is object => | ||
typeof x === 'object' && x !== null; | ||
@@ -49,7 +47,6 @@ // Properties that are both non-configurable and non-writable will break | ||
// See: https://github.com/dai-shi/proxy-compare/pull/8 | ||
const needsToCopyTargetObject = (obj: object) => ( | ||
const needsToCopyTargetObject = (obj: object) => | ||
Object.values(Object.getOwnPropertyDescriptors(obj)).some( | ||
(descriptor) => !descriptor.configurable && !descriptor.writable, | ||
) | ||
); | ||
); | ||
@@ -65,9 +62,11 @@ // Make a copy with all descriptors marked as configurable. | ||
const descriptors = Object.getOwnPropertyDescriptors(obj); | ||
Object.values(descriptors).forEach((desc) => { desc.configurable = true; }); | ||
Object.values(descriptors).forEach((desc) => { | ||
desc.configurable = true; | ||
}); | ||
return Object.create(getProto(obj), descriptors); | ||
}; | ||
type HasKeySet = Set<string | symbol> | ||
type HasOwnKeySet = Set<string | symbol> | ||
type KeysSet = Set<string | symbol> | ||
type HasKeySet = Set<string | symbol>; | ||
type HasOwnKeySet = Set<string | symbol>; | ||
type KeysSet = Set<string | symbol>; | ||
type Used = { | ||
@@ -86,3 +85,3 @@ [HAS_KEY_PROPERTY]?: HasKeySet; | ||
[AFFECTED_PROPERTY]?: Affected; | ||
} | ||
}; | ||
type ProxyCache<T extends object> = WeakMap< | ||
@@ -97,3 +96,6 @@ object, | ||
const createProxyHandler = <T extends object>(origObj: T, isTargetCopied: boolean) => { | ||
const createProxyHandler = <T extends object>( | ||
origObj: T, | ||
isTargetCopied: boolean, | ||
) => { | ||
const state: ProxyHandlerState<T> = { | ||
@@ -141,3 +143,3 @@ [IS_TARGET_COPIED_PROPERTY]: isTargetCopied, | ||
Reflect.get(target, key), | ||
(state[AFFECTED_PROPERTY] as Affected), | ||
state[AFFECTED_PROPERTY] as Affected, | ||
state[PROXY_CACHE_PROPERTY], | ||
@@ -170,8 +172,7 @@ state[TARGET_CACHE_PROPERTY], | ||
const getOriginalObject = <T extends object>(obj: T) => ( | ||
const getOriginalObject = <T extends object>(obj: T) => | ||
// unwrap proxy | ||
(obj as { [GET_ORIGINAL_SYMBOL]?: typeof obj })[GET_ORIGINAL_SYMBOL] | ||
(obj as { [GET_ORIGINAL_SYMBOL]?: typeof obj })[GET_ORIGINAL_SYMBOL] || | ||
// otherwise | ||
|| obj | ||
); | ||
obj; | ||
@@ -216,5 +217,4 @@ /** | ||
if (!isObjectToTrack(obj)) return obj; | ||
let targetAndCopied = ( | ||
targetCache && (targetCache as TargetCache<typeof obj>).get(obj) | ||
); | ||
let targetAndCopied = | ||
targetCache && (targetCache as TargetCache<typeof obj>).get(obj); | ||
if (!targetAndCopied) { | ||
@@ -230,8 +230,7 @@ const target = getOriginalObject(obj); | ||
const [target, copiedTarget] = targetAndCopied; | ||
let handlerAndState = ( | ||
proxyCache && (proxyCache as ProxyCache<typeof target>).get(target) | ||
); | ||
let handlerAndState = | ||
proxyCache && (proxyCache as ProxyCache<typeof target>).get(target); | ||
if ( | ||
!handlerAndState | ||
|| handlerAndState[1][IS_TARGET_COPIED_PROPERTY] !== !!copiedTarget | ||
!handlerAndState || | ||
handlerAndState[1][IS_TARGET_COPIED_PROPERTY] !== !!copiedTarget | ||
) { | ||
@@ -248,4 +247,8 @@ handlerAndState = createProxyHandler<typeof target>(target, !!copiedTarget); | ||
handlerAndState[1][AFFECTED_PROPERTY] = affected as Affected; | ||
handlerAndState[1][PROXY_CACHE_PROPERTY] = proxyCache as ProxyCache<object> | undefined; | ||
handlerAndState[1][TARGET_CACHE_PROPERTY] = targetCache as TargetCache<object> | undefined; | ||
handlerAndState[1][PROXY_CACHE_PROPERTY] = proxyCache as | ||
| ProxyCache<object> | ||
| undefined; | ||
handlerAndState[1][TARGET_CACHE_PROPERTY] = targetCache as | ||
| TargetCache<object> | ||
| undefined; | ||
return handlerAndState[1][PROXY_PROPERTY] as typeof target; | ||
@@ -257,10 +260,15 @@ }; | ||
const nextKeys = Reflect.ownKeys(nextObj); | ||
return prevKeys.length !== nextKeys.length | ||
|| prevKeys.some((k, i) => k !== nextKeys[i]); | ||
return ( | ||
prevKeys.length !== nextKeys.length || | ||
prevKeys.some((k, i) => k !== nextKeys[i]) | ||
); | ||
}; | ||
type ChangedCache = WeakMap<object, { | ||
[NEXT_OBJECT_PROPERTY]: object; | ||
[CHANGED_PROPERTY]: boolean; | ||
}>; | ||
type ChangedCache = WeakMap< | ||
object, | ||
{ | ||
[NEXT_OBJECT_PROPERTY]: object; | ||
[CHANGED_PROPERTY]: boolean; | ||
} | ||
>; | ||
@@ -459,3 +467,4 @@ /** | ||
} | ||
const used = isObject(x) && (affected as Affected).get(getOriginalObject(x)); | ||
const used = | ||
isObject(x) && (affected as Affected).get(getOriginalObject(x)); | ||
if (used) { | ||
@@ -476,3 +485,6 @@ used[HAS_KEY_PROPERTY]?.forEach((key) => { | ||
used[KEYS_PROPERTY]?.forEach((key) => { | ||
if (!onlyWithValues || 'value' in (Object.getOwnPropertyDescriptor(x, key) || {})) { | ||
if ( | ||
!onlyWithValues || | ||
'value' in (Object.getOwnPropertyDescriptor(x, key) || {}) | ||
) { | ||
walk((x as any)[key], path ? [...path, key] : [key]); | ||
@@ -479,0 +491,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1564
232
Yes
68335
13
9
1