@rjsf/utils 6.5.0 → 6.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { useRef } from 'react';
3
- import isEqual from 'lodash-es/isEqual.js';
3
+ import deepEquals from './deepEquals.js';
4
4
  /** Hook that stores and returns a `T` value. If `newValue` is the same as the stored one, then the stored one is
5
5
  * returned to avoid having a component rerender due it being a different object. Otherwise, the `newValue` is stored
6
6
  * and returned.
@@ -10,7 +10,7 @@ import isEqual from 'lodash-es/isEqual.js';
10
10
  */
11
11
  export default function useDeepCompareMemo(newValue) {
12
12
  const valueRef = useRef(newValue);
13
- if (!isEqual(newValue, valueRef.current)) {
13
+ if (!deepEquals(newValue, valueRef.current)) {
14
14
  valueRef.current = newValue;
15
15
  }
16
16
  return valueRef.current;
@@ -1 +1 @@
1
- {"version":3,"file":"useDeepCompareMemo.js","sourceRoot":"","sources":["../src/useDeepCompareMemo.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,OAAO,MAAM,gBAAgB,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAc,QAAW;IACjE,MAAM,QAAQ,GAAG,MAAM,CAAI,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC9B,CAAC;IACD,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"useDeepCompareMemo.js","sourceRoot":"","sources":["../src/useDeepCompareMemo.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE/B,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAc,QAAW;IACjE,MAAM,QAAQ,GAAG,MAAM,CAAI,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC9B,CAAC;IACD,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rjsf/utils",
3
- "version": "6.5.0",
3
+ "version": "6.5.2",
4
4
  "main": "dist/index.js",
5
5
  "module": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -66,6 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@x0k/json-schema-merge": "^1.0.3",
69
+ "fast-equals": "^6.0.0",
69
70
  "fast-uri": "^3.1.0",
70
71
  "jsonpointer": "^5.0.1",
71
72
  "lodash": "^4.18.1",
package/src/deepEquals.ts CHANGED
@@ -1,19 +1,20 @@
1
- import isEqualWith from 'lodash/isEqualWith';
1
+ import { createCustomEqual } from 'fast-equals';
2
2
 
3
- /** Implements a deep equals using the `lodash.isEqualWith` function, that provides a customized comparator that
4
- * assumes all functions are equivalent.
3
+ /** Implements a deep equals using `fast-equals.createCustomEqual`. Functions
4
+ * are always considered equal, and circular references are tracked to avoid
5
+ * infinite recursion on self-referential inputs.
5
6
  *
6
7
  * @param a - The first element to compare
7
8
  * @param b - The second element to compare
8
9
  * @returns - True if the `a` and `b` are deeply equal, false otherwise
9
10
  */
10
- export default function deepEquals(a: any, b: any): boolean {
11
- return isEqualWith(a, b, (obj: any, other: any) => {
12
- if (typeof obj === 'function' && typeof other === 'function') {
13
- // Assume all functions are equivalent
14
- // see https://github.com/rjsf-team/react-jsonschema-form/issues/255
15
- return true;
16
- }
17
- return undefined; // fallback to default isEquals behavior
18
- });
19
- }
11
+ const deepEquals = createCustomEqual({
12
+ circular: true,
13
+ createCustomConfig: () => ({
14
+ areFunctionsEqual(_a, b) {
15
+ return typeof b === 'function';
16
+ },
17
+ }),
18
+ });
19
+
20
+ export default deepEquals;
@@ -1,6 +1,6 @@
1
- import isEqual from 'lodash/isEqual';
2
1
  import omit from 'lodash/omit';
3
2
 
3
+ import deepEquals from './deepEquals';
4
4
  import { FormContextType, Registry, RJSFSchema, StrictRJSFSchema } from './types';
5
5
  import { REF_KEY, RJSF_REF_KEY } from './constants';
6
6
 
@@ -20,12 +20,12 @@ export default function isRootSchema<T = any, S extends StrictRJSFSchema = RJSFS
20
20
  schemaToCompare: S,
21
21
  ): boolean {
22
22
  const { rootSchema, schemaUtils } = registry;
23
- if (isEqual(schemaToCompare, rootSchema)) {
23
+ if (deepEquals(schemaToCompare, rootSchema)) {
24
24
  return true;
25
25
  }
26
26
  if (REF_KEY in rootSchema) {
27
27
  const resolvedSchema = schemaUtils.retrieveSchema(rootSchema);
28
- return isEqual(schemaToCompare, omit(resolvedSchema, RJSF_REF_KEY));
28
+ return deepEquals(schemaToCompare, omit(resolvedSchema, RJSF_REF_KEY));
29
29
  }
30
30
  return false;
31
31
  }
@@ -1,7 +1,7 @@
1
1
  import get from 'lodash/get';
2
- import isEqual from 'lodash/isEqual';
3
2
 
4
3
  import { CONST_KEY, DEFAULT_KEY, PROPERTIES_KEY } from '../constants';
4
+ import deepEquals from '../deepEquals';
5
5
  import { Experimental_CustomMergeAllOf, FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
6
6
  import retrieveSchema from './retrieveSchema';
7
7
  import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema';
@@ -42,7 +42,7 @@ export default function findSelectedOptionInXxxOf<
42
42
  const data = get(formData, selectorField);
43
43
  if (data !== undefined) {
44
44
  return xxxOfs.find((xxx) => {
45
- return isEqual(
45
+ return deepEquals(
46
46
  get(xxx, [PROPERTIES_KEY, selectorField, DEFAULT_KEY], get(xxx, [PROPERTIES_KEY, selectorField, CONST_KEY])),
47
47
  data,
48
48
  );
@@ -547,11 +547,6 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
547
547
  : {};
548
548
 
549
549
  const keys = new Set<string>();
550
- if (isObject(defaults)) {
551
- Object.keys(defaults as GenericObjectType)
552
- .filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
553
- .forEach((key) => keys.add(key));
554
- }
555
550
  const formDataRequired: string[] = [];
556
551
  Object.keys(formData as GenericObjectType)
557
552
  .filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
@@ -559,6 +554,14 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
559
554
  keys.add(key);
560
555
  formDataRequired.push(key);
561
556
  });
557
+ // Only seed keys from schema defaults when formData has no additionalProperties of its own.
558
+ // If the user already has data (e.g. after a key rename), injecting default keys would
559
+ // re-add stale entries that no longer exist in formData.
560
+ if (isObject(defaults) && formDataRequired.length === 0) {
561
+ Object.keys(defaults as GenericObjectType)
562
+ .filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
563
+ .forEach((key) => keys.add(key));
564
+ }
562
565
  keys.forEach((key) => {
563
566
  const computedDefault = computeDefaults(validator, additionalPropertiesSchema as S, {
564
567
  rootSchema,
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
 
3
3
  import { useRef } from 'react';
4
- import isEqual from 'lodash/isEqual';
4
+
5
+ import deepEquals from './deepEquals';
5
6
 
6
7
  /** Hook that stores and returns a `T` value. If `newValue` is the same as the stored one, then the stored one is
7
8
  * returned to avoid having a component rerender due it being a different object. Otherwise, the `newValue` is stored
@@ -12,7 +13,7 @@ import isEqual from 'lodash/isEqual';
12
13
  */
13
14
  export default function useDeepCompareMemo<T = unknown>(newValue: T): T {
14
15
  const valueRef = useRef<T>(newValue);
15
- if (!isEqual(newValue, valueRef.current)) {
16
+ if (!deepEquals(newValue, valueRef.current)) {
16
17
  valueRef.current = newValue;
17
18
  }
18
19
  return valueRef.current;