diff --git a/package.json b/package.json index 2e946106..6cb9c250 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,6 @@ "embla-carousel-fade": "^8.3.1", "embla-carousel-vue": "^8.3.1", "embla-carousel-wheel-gestures": "^8.0.1", - "fast-deep-equal": "^3.1.3", "fuse.js": "^7.0.0", "get-port-please": "^3.1.2", "knitwork": "^1.1.0", diff --git a/playground-vue/vite.config.ts b/playground-vue/vite.config.ts index 0279f0c6..e88248bc 100644 --- a/playground-vue/vite.config.ts +++ b/playground-vue/vite.config.ts @@ -30,6 +30,6 @@ export default defineConfig({ ], optimizeDeps: { // prevents reloading page when navigating between components - include: ['radix-vue/namespaced', 'vaul-vue', 'fast-deep-equal', 'embla-carousel-vue', 'embla-carousel-autoplay', 'embla-carousel-auto-scroll', 'embla-carousel-auto-height', 'embla-carousel-class-names', 'embla-carousel-fade', 'embla-carousel-wheel-gestures'] + include: ['radix-vue/namespaced', 'vaul-vue', 'embla-carousel-vue', 'embla-carousel-autoplay', 'embla-carousel-auto-scroll', 'embla-carousel-auto-height', 'embla-carousel-class-names', 'embla-carousel-fade', 'embla-carousel-wheel-gestures'] } }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 10335c70..5da984ac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -79,9 +79,6 @@ importers: embla-carousel-wheel-gestures: specifier: ^8.0.1 version: 8.0.1(embla-carousel@8.3.1) - fast-deep-equal: - specifier: ^3.1.3 - version: 3.1.3 fuse.js: specifier: ^7.0.0 version: 7.0.0 diff --git a/src/module.ts b/src/module.ts index 1efe1bb5..3135b97a 100644 --- a/src/module.ts +++ b/src/module.ts @@ -127,8 +127,6 @@ export default defineNuxtModule({ addTemplates(options, nuxt, resolve) - nuxt.options.vite = defu(nuxt.options?.vite, { optimizeDeps: { include: ['fast-deep-equal'] } }) - if (nuxt.options.dev && nuxt.options.devtools.enabled && options.devtools?.enabled) { const templates = buildTemplates(options) nuxt.options.vite = defu(nuxt.options?.vite, { plugins: [devtoolsMetaPlugin({ resolve, templates, options })] }) diff --git a/src/runtime/components/InputMenu.vue b/src/runtime/components/InputMenu.vue index 95fe9157..fd536eb3 100644 --- a/src/runtime/components/InputMenu.vue +++ b/src/runtime/components/InputMenu.vue @@ -131,13 +131,12 @@ extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3'] import { computed, ref, toRef, onMounted } from 'vue' import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, TagsInputRoot, TagsInputItem, TagsInputItemText, TagsInputItemDelete, TagsInputInput, useForwardPropsEmits } from 'radix-vue' import { defu } from 'defu' -import * as isEqual from 'fast-deep-equal' import { reactivePick } from '@vueuse/core' import { useAppConfig } from '#imports' import { useButtonGroup } from '../composables/useButtonGroup' import { useComponentIcons } from '../composables/useComponentIcons' import { useFormField } from '../composables/useFormField' -import { get, escapeRegExp } from '../utils' +import { get, isEqual, escapeRegExp } from '../utils' import UIcon from './Icon.vue' import UAvatar from './Avatar.vue' import UChip from './Chip.vue' @@ -180,7 +179,7 @@ const ui = computed(() => inputMenu({ })) function displayValue(value: AcceptableValue): string { - const item = items.value.find(item => props.valueKey ? isEqual.default(get(item as Record, props.valueKey as string), value) : isEqual.default(item, value)) + const item = items.value.find(item => props.valueKey ? isEqual(get(item as Record, props.valueKey as string), value) : isEqual(item, value)) return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item) } diff --git a/src/runtime/components/SelectMenu.vue b/src/runtime/components/SelectMenu.vue index d7014044..108d75f2 100644 --- a/src/runtime/components/SelectMenu.vue +++ b/src/runtime/components/SelectMenu.vue @@ -121,13 +121,12 @@ extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3'] import { computed, toRef } from 'vue' import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, useForwardPropsEmits } from 'radix-vue' import { defu } from 'defu' -import * as isEqual from 'fast-deep-equal' import { reactivePick } from '@vueuse/core' import { useAppConfig } from '#imports' import { useButtonGroup } from '../composables/useButtonGroup' import { useComponentIcons } from '../composables/useComponentIcons' import { useFormField } from '../composables/useFormField' -import { get, escapeRegExp } from '../utils' +import { get, isEqual, escapeRegExp } from '../utils' import UIcon from './Icon.vue' import UAvatar from './Avatar.vue' import UChip from './Chip.vue' @@ -173,7 +172,7 @@ function displayValue(value: T | T[]): string { return value.map(v => displayValue(v)).join(', ') } - const item = items.value.find(item => props.valueKey ? isEqual.default(get(item as Record, props.valueKey as string), value) : isEqual.default(item, value)) + const item = items.value.find(item => props.valueKey ? isEqual(get(item as Record, props.valueKey as string), value) : isEqual(item, value)) return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item) } diff --git a/src/runtime/utils/index.ts b/src/runtime/utils/index.ts index df351a51..df26eb9b 100644 --- a/src/runtime/utils/index.ts +++ b/src/runtime/utils/index.ts @@ -55,6 +55,34 @@ export function set(object: Record, path: (string | number)[] | str }, object) } +export function isEqual(a: any, b: any): boolean { + // Handle primitive types and referential equality + if (a === b) return true + + // Handle null/undefined cases + if (a == null || b == null) return a === b + + // Handle different types + if (typeof a !== typeof b) return false + + // Handle arrays + if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) return false + return a.every((item, index) => isEqual(item, b[index])) + } + + // Handle objects + if (typeof a === 'object') { + const keysA = Object.keys(a) + const keysB = Object.keys(b) + + if (keysA.length !== keysB.length) return false + return keysA.every(key => key in b && isEqual(a[key], b[key])) + } + + return false +} + export function looseToNumber(val: any): any { const n = Number.parseFloat(val) return Number.isNaN(n) ? val : n