@sjsf/form
Advanced tools
| import type { Schema, SchemaValue } from "./schema.js"; | ||
| export declare function isSchemaValueDeepEqual(a: SchemaValue | undefined, b: SchemaValue | undefined): boolean; | ||
| export declare const isSchemaValueDeepEqual: (a: SchemaValue | undefined, b: SchemaValue | undefined) => boolean; | ||
| export declare const isSchemaDeepEqual: (a: Schema | undefined, b: Schema | undefined) => boolean; | ||
| export declare const isOrderedSchemaDeepEqual: (a: Schema | undefined, b: Schema | undefined) => boolean; |
+52
-30
| import { isObject, isRecordProto } from "../lib/object.js"; | ||
| export function isSchemaValueDeepEqual(a, b) { | ||
| if (a === b) { | ||
| return true; | ||
| function compareRecords(a, b, compare) { | ||
| const aKeys = Object.keys(a); | ||
| let key; | ||
| for (let i = aKeys.length; i-- !== 0;) { | ||
| key = aKeys[i]; | ||
| if (!compare(a[key], b[key])) { | ||
| return false; | ||
| } | ||
| } | ||
| if (isObject(a) && isObject(b)) { | ||
| if (Array.isArray(a)) { | ||
| if (!Array.isArray(b)) { | ||
| return false; | ||
| } | ||
| const { length } = a; | ||
| if (length !== b.length) { | ||
| return false; | ||
| } | ||
| for (let i = length; i-- !== 0;) { | ||
| if (!isSchemaValueDeepEqual(a[i], b[i])) { | ||
| return Object.keys(b).length === aKeys.length; | ||
| } | ||
| function compareOrderedRecords(a, b, compare) { | ||
| const aKeys = Object.keys(a); | ||
| const bKeys = Object.keys(b); | ||
| if (aKeys.length !== bKeys.length) { | ||
| return false; | ||
| } | ||
| let key; | ||
| for (let i = aKeys.length; i-- !== 0;) { | ||
| key = aKeys[i]; | ||
| if (key !== bKeys[i] || !compare(a[key], b[key])) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| function createSchemaValueComparator(compareRecords) { | ||
| return function compare(a, b) { | ||
| if (a === b) { | ||
| return true; | ||
| } | ||
| if (isObject(a) && isObject(b)) { | ||
| if (Array.isArray(a)) { | ||
| if (!Array.isArray(b)) { | ||
| return false; | ||
| } | ||
| const { length } = a; | ||
| if (length !== b.length) { | ||
| return false; | ||
| } | ||
| for (let i = length; i-- !== 0;) { | ||
| if (!isSchemaValueDeepEqual(a[i], b[i])) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| return true; | ||
| } | ||
| if (Array.isArray(b) || | ||
| !isRecordProto(a) || | ||
| !isRecordProto(b)) { | ||
| // This should have been handled with === | ||
| return false; | ||
| } | ||
| const aKeys = Object.keys(a); | ||
| let key; | ||
| for (let i = aKeys.length; i-- !== 0;) { | ||
| key = aKeys[i]; | ||
| if (!isSchemaValueDeepEqual(a[key], b[key])) { | ||
| if (Array.isArray(b) || | ||
| !isRecordProto(a) || | ||
| !isRecordProto(b)) { | ||
| // This should have been handled with === | ||
| return false; | ||
| } | ||
| return compareRecords(a, b, compare); | ||
| } | ||
| return Object.keys(b).length === aKeys.length; | ||
| } | ||
| return a !== a && b !== b; | ||
| return a !== a && b !== b; | ||
| }; | ||
| } | ||
| export const isSchemaValueDeepEqual = createSchemaValueComparator(compareRecords); | ||
| export const isSchemaDeepEqual = isSchemaValueDeepEqual; | ||
| export const isOrderedSchemaDeepEqual = createSchemaValueComparator(compareOrderedRecords); |
@@ -98,5 +98,8 @@ // This file was copied and modified from https://github.com/rjsf-team/react-jsonschema-form/blob/f4229bf6e067d31b24de3ef9d3ca754ee52529ac/packages/utils/src/schema/getDefaultFormState.ts | ||
| else if (isSchemaObjectValue(defaults) && | ||
| isSchemaObjectValue(schemaDefault)) { | ||
| isSchemaObjectValue(schemaDefault) && | ||
| !schemaAnyOf && | ||
| !schemaOneOf && | ||
| !schemaRef) { | ||
| // For object defaults, only override parent defaults that are defined in | ||
| // schema.default. | ||
| // schema.default. Skip this for anyOf/oneOf/$ref schemas - they need special handling. | ||
| defaults = mergeSchemaObjects(defaults, schemaDefault); | ||
@@ -117,4 +120,9 @@ } | ||
| // If the referenced schema exists and parentDefaults is not set | ||
| // Then set the defaults from the current schema for the referenced schema | ||
| if (schemaToCompute && defaults === undefined) { | ||
| // Then set the defaults from the current schema for the referenced schema. | ||
| // Only do this if rawFormData has no meaningful data - we don't want to override user's existing values. | ||
| // Check for undefined OR empty object - rawFormData may be coerced to {} when not an object. | ||
| // CHANGED: this expression can be simplified | ||
| // const hasNoExistingData = rawFormData === undefined || (isObject(rawFormData) && isEmpty(rawFormData)); | ||
| const hasNoExistingData = isRecordEmpty(formData); | ||
| if (schemaToCompute && defaults === undefined && hasNoExistingData) { | ||
| defaults = schemaDefault; | ||
@@ -121,0 +129,0 @@ } |
| import { getContext, setContext } from "svelte"; | ||
| import { getDefaultValueForType, getSimpleSchemaType, isAdditionalProperty, isSchemaDeepEqual, isSchemaExpandable, isSchemaObjectValue, orderProperties, } from "../../core/index.js"; | ||
| import { getDefaultValueForType, getSimpleSchemaType, isAdditionalProperty, isOrderedSchemaDeepEqual, isSchemaExpandable, isSchemaObjectValue, orderProperties, } from "../../core/index.js"; | ||
| import { AFTER_SUBMITTED, getDefaultFieldState, ON_OBJECT_CHANGE, validateField, validateAdditionalPropertyKey, retrieveSchema, getFieldErrors, retrieveUiSchema, retrieveUiOption, uiTitleOption, markSchemaChange, getFieldsValidationMode, setFieldState, FIELD_CHANGED, getChildPath, } from "../../form/index.js"; | ||
@@ -16,7 +16,8 @@ import { createAdditionalPropertyKey, generateNewKey, createOriginalKeysOrder, } from "./model.js"; | ||
| // `ADDITIONAL_PROPERTY_FLAG` flag and `dependencies` resolution. | ||
| const retrievedSchema = $derived(retrieveSchema(ctx, config().schema, value())); | ||
| const retrievedSchema = $derived(retrieveSchema(ctx, config().schema, value(), true)); | ||
| let lastSchemaProperties = undefined; | ||
| const schemaProperties = $derived.by(() => { | ||
| const snap = $state.snapshot(retrievedSchema.properties); | ||
| if (!isSchemaDeepEqual(lastSchemaProperties, snap)) { | ||
| // NOTE: Cache hits are verified on `any-of` and `property-dependencies` examples. | ||
| if (!isOrderedSchemaDeepEqual(lastSchemaProperties, snap)) { | ||
| lastSchemaProperties = snap; | ||
@@ -87,3 +88,5 @@ } | ||
| const definition = schemaProperties[property] ?? false; | ||
| const schema = typeof definition === "boolean" ? {} : definition; | ||
| const schema = typeof definition === "boolean" | ||
| ? {} | ||
| : retrieveSchema(ctx, definition, value()?.[property]); | ||
| const uiSchema = retrieveUiSchema(ctx, isAdditional | ||
@@ -90,0 +93,0 @@ ? config.uiSchema.additionalProperties |
| <script lang="ts" generics="T"> | ||
| import { onDestroy } from 'svelte'; | ||
| import { createForm, type FormOptions } from "./create-form.svelte.js"; | ||
@@ -8,4 +10,8 @@ import BasicForm from "./basic-form.svelte"; | ||
| const form = createForm(options); | ||
| onDestroy(() => { | ||
| form.submission.abort() | ||
| form.fieldsValidation.abort() | ||
| }) | ||
| </script> | ||
| <BasicForm {form} /> |
@@ -19,3 +19,3 @@ import { type Schema, type SchemaValue } from "../../core/index.js"; | ||
| */ | ||
| export declare function retrieveSchema<T>(ctx: FormState<T>, schema: Schema, formData: SchemaValue | undefined): Schema; | ||
| export declare function retrieveSchema<T>(ctx: FormState<T>, schema: Schema, formData: SchemaValue | undefined, resolveAnyOfOrOneOfRefs?: boolean): Schema; | ||
| /** | ||
@@ -22,0 +22,0 @@ * @query |
@@ -24,4 +24,4 @@ import { isSelect as isSelectInternal, isFilesArray as isFilesArrayInternal, isMultiSelect as isMultiSelectInternal, retrieveSchema as retrieveSchemaInternal, sanitizeDataForNewSchema as sanitizeDataForNewSchemaInternal, getClosestMatchingOption as getClosestMatchingOptionInternal, } from "../../core/index.js"; | ||
| */ | ||
| export function retrieveSchema(ctx, schema, formData) { | ||
| return retrieveSchemaInternal(ctx[FORM_VALIDATOR], ctx[FORM_MERGER], schema, ctx[FORM_SCHEMA], formData); | ||
| export function retrieveSchema(ctx, schema, formData, resolveAnyOfOrOneOfRefs) { | ||
| return retrieveSchemaInternal(ctx[FORM_VALIDATOR], ctx[FORM_MERGER], schema, ctx[FORM_SCHEMA], formData, resolveAnyOfOrOneOfRefs); | ||
| } | ||
@@ -28,0 +28,0 @@ /** |
+3
-3
| { | ||
| "name": "@sjsf/form", | ||
| "version": "3.2.0", | ||
| "version": "3.2.1", | ||
| "description": "Svelte 5 library for creating forms based on JSON schema.", | ||
@@ -56,6 +56,6 @@ "license": "(MIT AND Apache-2.0)", | ||
| "deep-freeze-es6": "^5.0.0", | ||
| "globals": "16.5.0", | ||
| "globals": "17.0.0", | ||
| "json-schema-compare": "^0.2.2", | ||
| "json-schema-merge-allof": "^0.8.1", | ||
| "svelte": "^5.46.0" | ||
| "svelte": "^5.46.1" | ||
| }, | ||
@@ -62,0 +62,0 @@ "types": "./dist/form/index.d.ts", |
619915
0.3%13271
0.26%