fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

79
node_modules/proxy-compare/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,79 @@
# Change Log
## [Unreleased]
## [2.3.0] - 2022-08-13
### Added
- feat: support proxy-polyfill #41
### Changed
- fix: cache unfreeze results #44
## [2.2.0] - 2022-06-14
### Added
- Support nested proxy #38
## [2.1.0] - 2022-03-16
### Added
- Support getOwnPropertyDescriptor handler #34
## [2.0.3] - 2022-02-28
### Changed
- Fix affectedToPathList to avoid maximum call stack size exceeded error (#32)
## [2.0.2] - 2021-08-13
### Changed
- Fix package.json properly for ESM (#24)
## [2.0.1] - 2021-06-29
### Changed
- Fix package.json for React Native (#21)
## [2.0.0] - 2021-05-15
### Changed
- Drop mode in isDeepChanged [BREAKING CHANGE] (#18)
- Rename exported functions [BREAKING CHANGE] (#19)
## [1.1.6] - 2021-01-21
### Changed
- Fix object frozen afterwards (#9)
- Some refactors
## [1.1.5] - 2021-01-20
### Changed
- Fix read-only and non-configurable error (#8)
## [1.1.4] - 2021-01-14
### Changed
- The markToTrack util takes optional second argument
## [1.1.3] - 2020-11-24
### Added
- New markToTrack util
## [1.1.2] - 2020-11-21
### Changed
- Improve copying frozen objects
## [1.1.1] - 2020-11-20
### Changed
- Avoid mutating frozen objects
## [1.1.0] - 2020-11-18
### Changed
- Fix `MODE_IGNORE_REF_EQUALITY` behavior
## [1.0.3] - 2020-11-01
### Added
- affectedToPathList util
## [1.0.2] - 2020-07-02
### Changed
- Modern build
## [1.0.1] - 2020-03-09
### Changed
- Improve types
## [1.0.0] - 2020-03-08
### Added
- Initial release

21
node_modules/proxy-compare/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020-2022 Daishi Kato
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

212
node_modules/proxy-compare/README.md generated vendored Normal file
View File

@@ -0,0 +1,212 @@
# proxy-compare
[![CI](https://img.shields.io/github/workflow/status/dai-shi/proxy-compare/CI)](https://github.com/dai-shi/proxy-compare/actions?query=workflow%3ACI)
[![npm](https://img.shields.io/npm/v/proxy-compare)](https://www.npmjs.com/package/proxy-compare)
[![size](https://img.shields.io/bundlephobia/minzip/proxy-compare)](https://bundlephobia.com/result?p=proxy-compare)
Compare two objects using accessed properties with Proxy
## Introduction
This is an internal library used in [React Tracked](https://react-tracked.js.org).
## Install
```bash
npm install proxy-compare
```
## Usage
```javascript
$ node
> const { createProxy, isChanged } = require('proxy-compare')
undefined
> state = { a: 1, b: 2 }
{ a: 1, b: 2 }
> affected = new WeakMap()
WeakMap { [items unknown] }
> proxy = createProxy(state, affected)
Proxy [
{ a: 1, b: 2 },
{
get: [Function: get],
has: [Function: has],
getOwnPropertyDescriptor: [Function: getOwnPropertyDescriptor],
ownKeys: [Function: ownKeys]
}
]
> proxy.a
1
> isChanged(state, { a: 1, b: 22 }, affected)
false
> isChanged(state, { a: 11, b: 2 }, affected)
true
```
## API
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
### createProxy
Create a proxy.
This function will create a proxy at top level and proxy nested objects as you access them,
in order to keep track of which properties were accessed via get/has proxy handlers:
NOTE: Printing of WeakMap is hard to inspect and not very readable
for this purpose you can use the `affectedToPathList` helper.
#### Parameters
* `obj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object that will be wrapped on the proxy.
* `affected` **[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 hold the tracking of which properties in the proxied object were accessed.
* `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.
#### Examples
```javascript
import { createProxy } from 'proxy-compare';
const original = { a: "1", c: "2", d: { e: "3" } };
const affected = new WeakMap();
const proxy = createProxy(original, affected);
proxy.a // Will mark as used and track its value.
// This will update the affected WeakMap with original as key
// and a Set with "a"
proxy.d // Will mark "d" as accessed to track and proxy itself ({ e: "3" }).
// This will update the affected WeakMap with original as key
// and a Set with "d"
```
Returns **[Proxy](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Proxy)<[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)>** Object wrapped in a proxy.
### isChanged
Compare changes on objects.
This will compare the affected properties on tracked objects inside the proxy
to check if there were any changes made to it,
by default if no property was accessed on the proxy it will attempt to do a
reference equality check for the objects provided (Object.is(a, b)). If you access a property
on the proxy, then isChanged will only compare the affected properties.
#### Parameters
* `prevObj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The previous object to compare.
* `nextObj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object to compare with the previous one.
* `affected` **[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 holds the tracking of which properties in the proxied object were accessed.
* `cache` **[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 holds a cache of the comparisons for better performance with repetitive comparisons,
and to avoid infinite loop with circular structures.
#### Examples
```javascript
import { createProxy, isChanged } from 'proxy-compare';
const obj = { a: "1", c: "2", d: { e: "3" } };
const affected = new WeakMap();
const proxy = createProxy(obj, affected);
proxy.a
isChanged(obj, { a: "1" }, affected) // false
proxy.a = "2"
isChanged(obj, { a: "1" }, affected) // true
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Boolean indicating if the affected property on the object has changed.
### getUntracked
Unwrap proxy to get the original object.
Used to retrieve the original object used to create the proxy instance with `createProxy`.
#### Parameters
* `obj` **[Proxy](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Proxy)<[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)>** The proxy wrapper of the originial object.
#### Examples
```javascript
import { createProxy, getUntracked } from 'proxy-compare';
const original = { a: "1", c: "2", d: { e: "3" } };
const affected = new WeakMap();
const proxy = createProxy(original, affected);
const originalFromProxy = getUntracked(proxy)
Object.is(original, originalFromProxy) // true
isChanged(original, originalFromProxy, affected) // false
```
Returns **([object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) | null)** Return either the unwrapped object if exists.
### markToTrack
Mark object to be tracked.
This function marks an object that will be passed into `createProxy`
as marked to track or not. By default only Array and Object are marked to track,
so this is useful for example to mark a class instance to track or to mark a object
to be untracked when creating your proxy.
#### Parameters
* `obj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object to mark as tracked or not.
* `mark` Boolean indicating whether you want to track this object or not. (optional, default `true`)
#### Examples
```javascript
import { createProxy, markToTrack, isChanged } from 'proxy-compare';
const nested = { e: "3" }
markToTrack(nested, false)
const original = { a: "1", c: "2", d: nested };
const affected = new WeakMap();
const proxy = createProxy(original, affected);
proxy.d.e
isChanged(original, { d: { e: "3" } }, affected) // true
```
Returns **any** No return.
### replaceNewProxy
replace newProxy function.
This can be used if you want to use proxy-polyfill.
Note that proxy-polyfill can't polyfill everything.
Use it at your own risk.
#### Parameters
* `fn` **any**
## Projects using this library
* [react-tracked](https://github.com/dai-shi/react-tracked)
* [reactive-react-redux](https://github.com/dai-shi/reactive-react-redux)
* [svelte3-redux](https://github.com/dai-shi/svelte3-redux)
* [proxy-memoize](https://github.com/dai-shi/proxy-memoize)
* [valtio](https://github.com/pmndrs/valtio)
## Similar libraries
* [proxyequal](https://www.npmjs.com/package/proxyequal)
* [proxy-state-tree](https://www.npmjs.com/package/proxy-state-tree)
* [proxy-watcher](https://www.npmjs.com/package/proxy-watcher)

2
node_modules/proxy-compare/dist/index.modern.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
const e=Symbol(),t=Symbol(),r=Symbol();let n=(e,t)=>new Proxy(e,t);const o=Object.getPrototypeOf,s=new WeakMap,c=e=>e&&(s.has(e)?s.get(e):o(e)===Object.prototype||o(e)===Array.prototype),l=e=>"object"==typeof e&&null!==e,a=new WeakMap,f=e=>e[r]||e,i=(s,l,p)=>{if(!c(s))return s;const y=f(s),u=(e=>Object.isFrozen(e)||Object.values(Object.getOwnPropertyDescriptors(e)).some(e=>!e.writable))(y);let g=p&&p.get(y);return g&&g[1].f===u||(g=((n,o)=>{const s={f:o};let c=!1;const l=(t,r)=>{if(!c){let o=s.a.get(n);o||(o=new Set,s.a.set(n,o)),r&&o.has(e)||o.add(t)}},a={get:(e,t)=>t===r?n:(l(t),i(e[t],s.a,s.c)),has:(e,r)=>r===t?(c=!0,s.a.delete(n),!0):(l(r),r in e),getOwnPropertyDescriptor:(e,t)=>(l(t,!0),Object.getOwnPropertyDescriptor(e,t)),ownKeys:t=>(l(e),Reflect.ownKeys(t))};return o&&(a.set=a.deleteProperty=()=>!1),[a,s]})(y,u),g[1].p=n(u?(e=>{let t=a.get(e);if(!t){if(Array.isArray(e))t=Array.from(e);else{const r=Object.getOwnPropertyDescriptors(e);Object.values(r).forEach(e=>{e.configurable=!0}),t=Object.create(o(e),r)}a.set(e,t)}return t})(y):y,g[0]),p&&p.set(y,g)),g[1].a=l,g[1].c=p,g[1].p},p=(e,t)=>{const r=Reflect.ownKeys(e),n=Reflect.ownKeys(t);return r.length!==n.length||r.some((e,t)=>e!==n[t])},y=(t,r,n,o)=>{if(Object.is(t,r))return!1;if(!l(t)||!l(r))return!0;const s=n.get(f(t));if(!s)return!0;if(o){const e=o.get(t);if(e&&e.n===r)return e.g;o.set(t,{n:r,g:!1})}let c=null;for(const l of s){const s=l===e?p(t,r):y(t[l],r[l],n,o);if(!0!==s&&!1!==s||(c=s),c)break}return null===c&&(c=!0),o&&o.set(t,{n:r,g:c}),c},u=e=>!!c(e)&&t in e,g=e=>c(e)&&e[r]||null,b=(e,t=!0)=>{s.set(e,t)},O=(e,t)=>{const r=[],n=new WeakSet,o=(e,s)=>{if(n.has(e))return;l(e)&&n.add(e);const c=l(e)&&t.get(f(e));c?c.forEach(t=>{o(e[t],s?[...s,t]:[t])}):s&&r.push(s)};return o(e),r},w=e=>{n=e};export{O as affectedToPathList,i as createProxy,g as getUntracked,y as isChanged,b as markToTrack,w as replaceNewProxy,u as trackMemo};
//# sourceMappingURL=index.modern.mjs.map

1
node_modules/proxy-compare/dist/index.modern.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

2
node_modules/proxy-compare/dist/index.modern.mjs generated vendored Normal file
View File

@@ -0,0 +1,2 @@
const e=Symbol(),t=Symbol(),r=Symbol();let n=(e,t)=>new Proxy(e,t);const o=Object.getPrototypeOf,s=new WeakMap,c=e=>e&&(s.has(e)?s.get(e):o(e)===Object.prototype||o(e)===Array.prototype),l=e=>"object"==typeof e&&null!==e,a=new WeakMap,f=e=>e[r]||e,i=(s,l,p)=>{if(!c(s))return s;const y=f(s),u=(e=>Object.isFrozen(e)||Object.values(Object.getOwnPropertyDescriptors(e)).some(e=>!e.writable))(y);let g=p&&p.get(y);return g&&g[1].f===u||(g=((n,o)=>{const s={f:o};let c=!1;const l=(t,r)=>{if(!c){let o=s.a.get(n);o||(o=new Set,s.a.set(n,o)),r&&o.has(e)||o.add(t)}},a={get:(e,t)=>t===r?n:(l(t),i(e[t],s.a,s.c)),has:(e,r)=>r===t?(c=!0,s.a.delete(n),!0):(l(r),r in e),getOwnPropertyDescriptor:(e,t)=>(l(t,!0),Object.getOwnPropertyDescriptor(e,t)),ownKeys:t=>(l(e),Reflect.ownKeys(t))};return o&&(a.set=a.deleteProperty=()=>!1),[a,s]})(y,u),g[1].p=n(u?(e=>{let t=a.get(e);if(!t){if(Array.isArray(e))t=Array.from(e);else{const r=Object.getOwnPropertyDescriptors(e);Object.values(r).forEach(e=>{e.configurable=!0}),t=Object.create(o(e),r)}a.set(e,t)}return t})(y):y,g[0]),p&&p.set(y,g)),g[1].a=l,g[1].c=p,g[1].p},p=(e,t)=>{const r=Reflect.ownKeys(e),n=Reflect.ownKeys(t);return r.length!==n.length||r.some((e,t)=>e!==n[t])},y=(t,r,n,o)=>{if(Object.is(t,r))return!1;if(!l(t)||!l(r))return!0;const s=n.get(f(t));if(!s)return!0;if(o){const e=o.get(t);if(e&&e.n===r)return e.g;o.set(t,{n:r,g:!1})}let c=null;for(const l of s){const s=l===e?p(t,r):y(t[l],r[l],n,o);if(!0!==s&&!1!==s||(c=s),c)break}return null===c&&(c=!0),o&&o.set(t,{n:r,g:c}),c},u=e=>!!c(e)&&t in e,g=e=>c(e)&&e[r]||null,b=(e,t=!0)=>{s.set(e,t)},O=(e,t)=>{const r=[],n=new WeakSet,o=(e,s)=>{if(n.has(e))return;l(e)&&n.add(e);const c=l(e)&&t.get(f(e));c?c.forEach(t=>{o(e[t],s?[...s,t]:[t])}):s&&r.push(s)};return o(e),r},w=e=>{n=e};export{O as affectedToPathList,i as createProxy,g as getUntracked,y as isChanged,b as markToTrack,w as replaceNewProxy,u as trackMemo};
//# sourceMappingURL=index.modern.mjs.map

1
node_modules/proxy-compare/dist/index.modern.mjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

2
node_modules/proxy-compare/dist/index.umd.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e||self).proxyCompare={})}(this,function(e){function t(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var r=Symbol(),n=Symbol(),o=Symbol(),i=function(e,t){return new Proxy(e,t)},a=Object.getPrototypeOf,u=new WeakMap,c=function(e){return e&&(u.has(e)?u.get(e):a(e)===Object.prototype||a(e)===Array.prototype)},f=function(e){return"object"==typeof e&&null!==e},l=new WeakMap,s=function(e){return e[o]||e},y=function(e,t,u){if(!c(e))return e;var f=s(e),p=function(e){return Object.isFrozen(e)||Object.values(Object.getOwnPropertyDescriptors(e)).some(function(e){return!e.writable})}(f),b=u&&u.get(f);return b&&b[1].f===p||((b=function(e,t){var i,a=((i={}).f=t,i),u=!1,c=function(t,n){if(!u){var o=a.a.get(e);o||(o=new Set,a.a.set(e,o)),n&&o.has(r)||o.add(t)}},f={get:function(t,r){return r===o?e:(c(r),y(t[r],a.a,a.c))},has:function(t,r){return r===n?(u=!0,a.a.delete(e),!0):(c(r),r in t)},getOwnPropertyDescriptor:function(e,t){return c(t,!0),Object.getOwnPropertyDescriptor(e,t)},ownKeys:function(e){return c(r),Reflect.ownKeys(e)}};return t&&(f.set=f.deleteProperty=function(){return!1}),[f,a]}(f,p))[1].p=i(p?function(e){var t=l.get(e);if(!t){if(Array.isArray(e))t=Array.from(e);else{var r=Object.getOwnPropertyDescriptors(e);Object.values(r).forEach(function(e){e.configurable=!0}),t=Object.create(a(e),r)}l.set(e,t)}return t}(f):f,b[0]),u&&u.set(f,b)),b[1].a=t,b[1].c=u,b[1].p},p=function(e,t){var r=Reflect.ownKeys(e),n=Reflect.ownKeys(t);return r.length!==n.length||r.some(function(e,t){return e!==n[t]})};e.affectedToPathList=function(e,t){var r=[],n=new WeakSet;return function e(o,i){if(!n.has(o)){f(o)&&n.add(o);var a=f(o)&&t.get(s(o));a?a.forEach(function(t){e(o[t],i?[].concat(i,[t]):[t])}):i&&r.push(i)}}(e),r},e.createProxy=y,e.getUntracked=function(e){return c(e)&&e[o]||null},e.isChanged=function e(n,o,i,a){if(Object.is(n,o))return!1;if(!f(n)||!f(o))return!0;var u=i.get(s(n));if(!u)return!0;if(a){var c,l=a.get(n);if(l&&l.n===o)return l.g;a.set(n,((c={}).n=o,c.g=!1,c))}for(var y,b,d=null,g=function(e,r){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,r){if(e){if("string"==typeof e)return t(e,r);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?t(e,r):void 0}}(e))){n&&(e=n);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(u);!(y=g()).done;){var v=y.value,m=v===r?p(n,o):e(n[v],o[v],i,a);if(!0!==m&&!1!==m||(d=m),d)break}return null===d&&(d=!0),a&&a.set(n,((b={}).n=o,b.g=d,b)),d},e.markToTrack=function(e,t){void 0===t&&(t=!0),u.set(e,t)},e.replaceNewProxy=function(e){i=e},e.trackMemo=function(e){return!!c(e)&&n in e}});
//# sourceMappingURL=index.umd.js.map

1
node_modules/proxy-compare/dist/index.umd.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

129
node_modules/proxy-compare/dist/src/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,129 @@
declare let newProxy: <T extends object>(target: T, handler: ProxyHandler<T>) => T;
/**
* Create a proxy.
*
* This function will create a proxy at top level and proxy nested objects as you access them,
* in order to keep track of which properties were accessed via get/has proxy handlers:
*
* NOTE: Printing of WeakMap is hard to inspect and not very readable
* for this purpose you can use the `affectedToPathList` helper.
*
* @param {object} obj - Object that will be wrapped on the proxy.
* @param {WeakMap<object, unknown>} affected -
* WeakMap that will hold the tracking of which properties in the proxied object were accessed.
* @param {WeakMap<object, unknown>} [proxyCache] -
* WeakMap that will help keep referential identity for proxies.
* @returns {Proxy<object>} - Object wrapped in a proxy.
*
* @example
* import { createProxy } from 'proxy-compare';
*
* const original = { a: "1", c: "2", d: { e: "3" } };
* const affected = new WeakMap();
* const proxy = createProxy(original, affected);
*
* proxy.a // Will mark as used and track its value.
* // This will update the affected WeakMap with original as key
* // and a Set with "a"
*
* proxy.d // Will mark "d" as accessed to track and proxy itself ({ e: "3" }).
* // This will update the affected WeakMap with original as key
* // and a Set with "d"
*/
export declare const createProxy: <T>(obj: T, affected: WeakMap<object, unknown>, proxyCache?: WeakMap<object, unknown>) => T;
/**
* Compare changes on objects.
*
* This will compare the affected properties on tracked objects inside the proxy
* to check if there were any changes made to it,
* by default if no property was accessed on the proxy it will attempt to do a
* reference equality check for the objects provided (Object.is(a, b)). If you access a property
* on the proxy, then isChanged will only compare the affected properties.
*
* @param {object} prevObj - The previous object to compare.
* @param {object} nextObj - Object to compare with the previous one.
* @param {WeakMap<object, unknown>} affected -
* WeakMap that holds the tracking of which properties in the proxied object were accessed.
* @param {WeakMap<object, unknown>} [cache] -
* WeakMap that holds a cache of the comparisons for better performance with repetitive comparisons,
* and to avoid infinite loop with circular structures.
* @returns {boolean} - Boolean indicating if the affected property on the object has changed.
*
* @example
* import { createProxy, isChanged } from 'proxy-compare';
*
* const obj = { a: "1", c: "2", d: { e: "3" } };
* const affected = new WeakMap();
*
* const proxy = createProxy(obj, affected);
*
* proxy.a
*
* isChanged(obj, { a: "1" }, affected) // false
*
* proxy.a = "2"
*
* isChanged(obj, { a: "1" }, affected) // true
*/
export declare const isChanged: (prevObj: unknown, nextObj: unknown, affected: WeakMap<object, unknown>, cache?: WeakMap<object, unknown>) => boolean;
export declare const trackMemo: (obj: unknown) => boolean;
/**
* Unwrap proxy to get the original object.
*
* Used to retrieve the original object used to create the proxy instance with `createProxy`.
*
* @param {Proxy<object>} obj - The proxy wrapper of the originial object.
* @returns {object | null} - Return either the unwrapped object if exists.
*
* @example
* import { createProxy, getUntracked } from 'proxy-compare';
*
* const original = { a: "1", c: "2", d: { e: "3" } };
* const affected = new WeakMap();
*
* const proxy = createProxy(original, affected);
* const originalFromProxy = getUntracked(proxy)
*
* Object.is(original, originalFromProxy) // true
* isChanged(original, originalFromProxy, affected) // false
*/
export declare const getUntracked: <T>(obj: T) => T | null;
/**
* Mark object to be tracked.
*
* This function marks an object that will be passed into `createProxy`
* as marked to track or not. By default only Array and Object are marked to track,
* so this is useful for example to mark a class instance to track or to mark a object
* to be untracked when creating your proxy.
*
* @param obj - Object to mark as tracked or not.
* @param mark - Boolean indicating whether you want to track this object or not.
* @returns No return.
*
* @example
* import { createProxy, markToTrack, isChanged } from 'proxy-compare';
*
* const nested = { e: "3" }
*
* markToTrack(nested, false)
*
* const original = { a: "1", c: "2", d: nested };
* const affected = new WeakMap();
*
* const proxy = createProxy(original, affected);
*
* proxy.d.e
*
* isChanged(original, { d: { e: "3" } }, affected) // true
*/
export declare const markToTrack: (obj: object, mark?: boolean) => void;
export declare const affectedToPathList: (obj: unknown, affected: WeakMap<object, unknown>) => (string | symbol)[][];
/**
* replace newProxy function.
*
* This can be used if you want to use proxy-polyfill.
* Note that proxy-polyfill can't polyfill everything.
* Use it at your own risk.
*/
export declare const replaceNewProxy: (fn: typeof newProxy) => void;
export {};

64
node_modules/proxy-compare/package.json generated vendored Normal file
View File

@@ -0,0 +1,64 @@
{
"name": "proxy-compare",
"description": "Compare two objects using accessed properties with Proxy",
"version": "2.3.0",
"author": "Daishi Kato",
"repository": {
"type": "git",
"url": "https://github.com/dai-shi/proxy-compare.git"
},
"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",
"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"
}
},
"sideEffects": false,
"files": [
"src",
"dist"
],
"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 --section API --markdown-toc false --parse-extension ts src/*.ts"
},
"jest": {
"preset": "ts-jest/presets/js-with-ts"
},
"keywords": [
"proxy",
"compare",
"equal",
"shallowequal",
"deepequal"
],
"license": "MIT",
"dependencies": {},
"devDependencies": {
"@types/jest": "^28.1.6",
"@typescript-eslint/eslint-plugin": "^5.33.0",
"@typescript-eslint/parser": "^5.33.0",
"documentation": "^13.2.5",
"eslint": "^8.21.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.26.0",
"jest": "^28.1.3",
"microbundle": "^0.15.1",
"npm-run-all": "^4.1.5",
"ts-jest": "^28.0.7",
"typescript": "^4.7.4"
}
}

404
node_modules/proxy-compare/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,404 @@
// symbols
const OWN_KEYS_SYMBOL = Symbol();
const TRACK_MEMO_SYMBOL = Symbol();
const GET_ORIGINAL_SYMBOL = Symbol();
// properties
const AFFECTED_PROPERTY = 'a';
const FROZEN_PROPERTY = 'f';
const PROXY_PROPERTY = 'p';
const PROXY_CACHE_PROPERTY = 'c';
const NEXT_OBJECT_PROPERTY = 'n';
const CHANGED_PROPERTY = 'g';
// function to create a new bare proxy
let newProxy = <T extends object>(
target: T,
handler: ProxyHandler<T>,
) => new Proxy(target, handler);
// get object prototype
const getProto = Object.getPrototypeOf;
const objectsToTrack = new WeakMap<object, boolean>();
// 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)
)
);
// check if it is object
const isObject = (x: unknown): x is object => (
typeof x === 'object' && x !== null
);
// check if frozen
const isFrozen = (obj: object) => (
Object.isFrozen(obj) || (
// Object.isFrozen() doesn't detect non-writable properties
// See: https://github.com/dai-shi/proxy-compare/pull/8
Object.values(Object.getOwnPropertyDescriptors(obj)).some(
(descriptor) => !descriptor.writable,
)
)
);
// copy frozen object
const unfrozenCache = new WeakMap<object, object>();
const unfreeze = <T extends object>(obj: T): T => {
let unfrozen = unfrozenCache.get(obj);
if (!unfrozen) {
if (Array.isArray(obj)) {
// Arrays need a special way to copy
unfrozen = Array.from(obj);
} else {
// For non-array objects, we create a new object keeping the prototype
// with changing all configurable options (otherwise, proxies will complain)
const descriptors = Object.getOwnPropertyDescriptors(obj);
Object.values(descriptors).forEach((desc) => { desc.configurable = true; });
unfrozen = Object.create(getProto(obj), descriptors);
}
unfrozenCache.set(obj, unfrozen as object);
}
return unfrozen as T;
};
type Affected = WeakMap<object, Set<string | symbol>>;
type ProxyHandlerState<T extends object> = {
readonly [FROZEN_PROPERTY]: boolean;
[PROXY_PROPERTY]?: T;
[PROXY_CACHE_PROPERTY]?: ProxyCache<object> | undefined;
[AFFECTED_PROPERTY]?: Affected;
}
type ProxyCache<T extends object> = WeakMap<
object,
readonly [ProxyHandler<T>, ProxyHandlerState<T>]
>;
const createProxyHandler = <T extends object>(origObj: T, frozen: boolean) => {
const state: ProxyHandlerState<T> = {
[FROZEN_PROPERTY]: frozen,
};
let trackObject = false; // for trackMemo
const recordUsage = (key: string | symbol, skipWithOwnKeys?: boolean) => {
if (!trackObject) {
let used = (state[AFFECTED_PROPERTY] as Affected).get(origObj);
if (!used) {
used = new Set();
(state[AFFECTED_PROPERTY] as Affected).set(origObj, used);
}
if (!skipWithOwnKeys || !used.has(OWN_KEYS_SYMBOL)) {
used.add(key);
}
}
};
const recordObjectAsUsed = () => {
trackObject = true;
(state[AFFECTED_PROPERTY] as Affected).delete(origObj);
};
const handler: ProxyHandler<T> = {
get(target, key) {
if (key === GET_ORIGINAL_SYMBOL) {
return origObj;
}
recordUsage(key);
return createProxy(
(target as any)[key],
(state[AFFECTED_PROPERTY] as Affected),
state[PROXY_CACHE_PROPERTY],
);
},
has(target, key) {
if (key === TRACK_MEMO_SYMBOL) {
recordObjectAsUsed();
return true;
}
// LIMITATION: We simply record the same as `get`.
// This means { a: {} } and { a: {} } is detected as changed,
// if `'a' in obj` is handled.
recordUsage(key);
return key in target;
},
getOwnPropertyDescriptor(target, key) {
// LIMITATION: We simply record the same as `get`.
// This means { a: {} } and { a: {} } is detected as changed,
// if `obj.getOwnPropertyDescriptor('a'))` is handled.
recordUsage(key, true);
return Object.getOwnPropertyDescriptor(target, key);
},
ownKeys(target) {
recordUsage(OWN_KEYS_SYMBOL);
return Reflect.ownKeys(target);
},
};
if (frozen) {
handler.set = handler.deleteProperty = () => false;
}
return [handler, state] as const;
};
const getOriginalObject = <T extends object>(obj: T) => (
// unwrap proxy
(obj as { [GET_ORIGINAL_SYMBOL]?: typeof obj })[GET_ORIGINAL_SYMBOL]
// otherwise
|| obj
);
/**
* Create a proxy.
*
* This function will create a proxy at top level and proxy nested objects as you access them,
* in order to keep track of which properties were accessed via get/has proxy handlers:
*
* NOTE: Printing of WeakMap is hard to inspect and not very readable
* for this purpose you can use the `affectedToPathList` helper.
*
* @param {object} obj - Object that will be wrapped on the proxy.
* @param {WeakMap<object, unknown>} affected -
* WeakMap that will hold the tracking of which properties in the proxied object were accessed.
* @param {WeakMap<object, unknown>} [proxyCache] -
* WeakMap that will help keep referential identity for proxies.
* @returns {Proxy<object>} - Object wrapped in a proxy.
*
* @example
* import { createProxy } from 'proxy-compare';
*
* const original = { a: "1", c: "2", d: { e: "3" } };
* const affected = new WeakMap();
* const proxy = createProxy(original, affected);
*
* proxy.a // Will mark as used and track its value.
* // This will update the affected WeakMap with original as key
* // and a Set with "a"
*
* proxy.d // Will mark "d" as accessed to track and proxy itself ({ e: "3" }).
* // This will update the affected WeakMap with original as key
* // and a Set with "d"
*/
export const createProxy = <T>(
obj: T,
affected: WeakMap<object, unknown>,
proxyCache?: WeakMap<object, unknown>,
): T => {
if (!isObjectToTrack(obj)) return obj;
const target = getOriginalObject(obj);
const frozen = isFrozen(target);
let handlerAndState = (
proxyCache && (proxyCache as ProxyCache<typeof target>).get(target)
);
if (!handlerAndState || handlerAndState[1][FROZEN_PROPERTY] !== frozen) {
handlerAndState = createProxyHandler<typeof target>(target, frozen);
handlerAndState[1][PROXY_PROPERTY] = newProxy(
frozen ? unfreeze(target) : target,
handlerAndState[0],
);
if (proxyCache) {
proxyCache.set(target, handlerAndState);
}
}
handlerAndState[1][AFFECTED_PROPERTY] = affected as Affected;
handlerAndState[1][PROXY_CACHE_PROPERTY] = proxyCache as ProxyCache<object> | undefined;
return handlerAndState[1][PROXY_PROPERTY] as typeof target;
};
const isOwnKeysChanged = (prevObj: object, nextObj: object) => {
const prevKeys = Reflect.ownKeys(prevObj);
const nextKeys = Reflect.ownKeys(nextObj);
return prevKeys.length !== nextKeys.length
|| prevKeys.some((k, i) => k !== nextKeys[i]);
};
type ChangedCache = WeakMap<object, {
[NEXT_OBJECT_PROPERTY]: object;
[CHANGED_PROPERTY]: boolean;
}>;
/**
* Compare changes on objects.
*
* This will compare the affected properties on tracked objects inside the proxy
* to check if there were any changes made to it,
* by default if no property was accessed on the proxy it will attempt to do a
* reference equality check for the objects provided (Object.is(a, b)). If you access a property
* on the proxy, then isChanged will only compare the affected properties.
*
* @param {object} prevObj - The previous object to compare.
* @param {object} nextObj - Object to compare with the previous one.
* @param {WeakMap<object, unknown>} affected -
* WeakMap that holds the tracking of which properties in the proxied object were accessed.
* @param {WeakMap<object, unknown>} [cache] -
* WeakMap that holds a cache of the comparisons for better performance with repetitive comparisons,
* and to avoid infinite loop with circular structures.
* @returns {boolean} - Boolean indicating if the affected property on the object has changed.
*
* @example
* import { createProxy, isChanged } from 'proxy-compare';
*
* const obj = { a: "1", c: "2", d: { e: "3" } };
* const affected = new WeakMap();
*
* const proxy = createProxy(obj, affected);
*
* proxy.a
*
* isChanged(obj, { a: "1" }, affected) // false
*
* proxy.a = "2"
*
* isChanged(obj, { a: "1" }, affected) // true
*/
export const isChanged = (
prevObj: unknown,
nextObj: unknown,
affected: WeakMap<object, unknown>,
cache?: WeakMap<object, unknown>,
): boolean => {
if (Object.is(prevObj, nextObj)) {
return false;
}
if (!isObject(prevObj) || !isObject(nextObj)) return true;
const used = (affected as Affected).get(getOriginalObject(prevObj));
if (!used) return true;
if (cache) {
const hit = (cache as ChangedCache).get(prevObj);
if (hit && hit[NEXT_OBJECT_PROPERTY] === nextObj) {
return hit[CHANGED_PROPERTY];
}
// for object with cycles
(cache as ChangedCache).set(prevObj, {
[NEXT_OBJECT_PROPERTY]: nextObj,
[CHANGED_PROPERTY]: false,
});
}
let changed: boolean | null = null;
// eslint-disable-next-line no-restricted-syntax
for (const key of used) {
const c = key === OWN_KEYS_SYMBOL ? isOwnKeysChanged(prevObj, nextObj)
: isChanged(
(prevObj as any)[key],
(nextObj as any)[key],
affected,
cache,
);
if (c === true || c === false) changed = c;
if (changed) break;
}
if (changed === null) changed = true;
if (cache) {
cache.set(prevObj, {
[NEXT_OBJECT_PROPERTY]: nextObj,
[CHANGED_PROPERTY]: changed,
});
}
return changed;
};
// explicitly track object with memo
export const trackMemo = (obj: unknown) => {
if (isObjectToTrack(obj)) {
return TRACK_MEMO_SYMBOL in obj;
}
return false;
};
/**
* Unwrap proxy to get the original object.
*
* Used to retrieve the original object used to create the proxy instance with `createProxy`.
*
* @param {Proxy<object>} obj - The proxy wrapper of the originial object.
* @returns {object | null} - Return either the unwrapped object if exists.
*
* @example
* import { createProxy, getUntracked } from 'proxy-compare';
*
* const original = { a: "1", c: "2", d: { e: "3" } };
* const affected = new WeakMap();
*
* const proxy = createProxy(original, affected);
* const originalFromProxy = getUntracked(proxy)
*
* Object.is(original, originalFromProxy) // true
* isChanged(original, originalFromProxy, affected) // false
*/
export const getUntracked = <T>(obj: T): T | null => {
if (isObjectToTrack(obj)) {
return (obj as { [GET_ORIGINAL_SYMBOL]?: T })[GET_ORIGINAL_SYMBOL] || null;
}
return null;
};
/**
* Mark object to be tracked.
*
* This function marks an object that will be passed into `createProxy`
* as marked to track or not. By default only Array and Object are marked to track,
* so this is useful for example to mark a class instance to track or to mark a object
* to be untracked when creating your proxy.
*
* @param obj - Object to mark as tracked or not.
* @param mark - Boolean indicating whether you want to track this object or not.
* @returns No return.
*
* @example
* import { createProxy, markToTrack, isChanged } from 'proxy-compare';
*
* const nested = { e: "3" }
*
* markToTrack(nested, false)
*
* const original = { a: "1", c: "2", d: nested };
* const affected = new WeakMap();
*
* const proxy = createProxy(original, affected);
*
* proxy.d.e
*
* isChanged(original, { d: { e: "3" } }, affected) // true
*/
export const markToTrack = (obj: object, mark = true) => {
objectsToTrack.set(obj, mark);
};
// convert affected to path list
export const affectedToPathList = (
obj: unknown,
affected: WeakMap<object, unknown>,
) => {
const list: (string | symbol)[][] = [];
const seen = new WeakSet();
const walk = (x: unknown, path?: (string | symbol)[]) => {
if (seen.has(x as object)) {
// for object with cycles
return;
}
if (isObject(x)) {
seen.add(x);
}
const used = isObject(x) && (affected as Affected).get(getOriginalObject(x));
if (used) {
used.forEach((key) => {
walk((x as any)[key], path ? [...path, key] : [key]);
});
} else if (path) {
list.push(path);
}
};
walk(obj);
return list;
};
/**
* replace newProxy function.
*
* This can be used if you want to use proxy-polyfill.
* Note that proxy-polyfill can't polyfill everything.
* Use it at your own risk.
*/
export const replaceNewProxy = (fn: typeof newProxy) => {
newProxy = fn;
};