From a5c9edb4da6cc51e61cdb6b47553c481a19c8ca1 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sat, 2 Jul 2022 10:53:06 +0300 Subject: [PATCH] Store partial icon data in storage to reduce memory usage --- components-demo/nuxt3-demo/nuxt.config.ts | 6 +- components-demo/nuxt3-demo/package.json | 2 +- components/ember/src/component.ts | 7 +- components/ember/src/render.ts | 2 +- components/react/src/iconify.ts | 16 +++-- components/react/src/offline.ts | 23 ++++-- components/svelte/src/functions.ts | 12 +++- components/svelte/src/offline-functions.ts | 12 +++- components/svg-framework/src/render/svg.ts | 4 +- components/svg-framework/src/scanner/index.ts | 18 +++-- components/vue/src/iconify.ts | 12 +++- components/vue/src/offline.ts | 23 +++--- components/vue2/src/iconify.ts | 6 +- components/vue2/src/offline.ts | 31 ++++---- components/vue2/src/render.ts | 31 ++++---- iconify-icon-demo/nuxt3-demo/nuxt.config.ts | 2 +- iconify-icon-demo/nuxt3-demo/package.json | 2 +- .../icon/src/attributes/icon/index.ts | 2 +- .../icon/src/attributes/icon/object.ts | 6 +- .../icon/src/attributes/icon/state.ts | 8 +-- iconify-icon/icon/src/render/icon.ts | 10 ++- iconify-icon/icon/tests/icon-load-api-test.ts | 3 - iconify-icon/icon/tests/icon-load-test.ts | 7 +- iconify-icon/icon/tests/icon-object-test.ts | 4 -- packages/core/src/api/icons.ts | 4 +- packages/core/src/storage/functions.ts | 31 ++++---- packages/core/src/storage/storage.ts | 16 ++--- .../tests/storage/storage-functions-test.ts | 36 ++++++---- packages/core/tests/storage/storage-test.ts | 49 ++----------- pnpm-lock.yaml | 70 +++++++++---------- 30 files changed, 228 insertions(+), 227 deletions(-) diff --git a/components-demo/nuxt3-demo/nuxt.config.ts b/components-demo/nuxt3-demo/nuxt.config.ts index 47ad6e4..6a897f7 100644 --- a/components-demo/nuxt3-demo/nuxt.config.ts +++ b/components-demo/nuxt3-demo/nuxt.config.ts @@ -1,6 +1,4 @@ -import { defineNuxtConfig } from 'nuxt3' +import { defineNuxtConfig } from 'nuxt'; // https://v3.nuxtjs.org/docs/directory-structure/nuxt.config -export default defineNuxtConfig({ - -}) +export default defineNuxtConfig({}); diff --git a/components-demo/nuxt3-demo/package.json b/components-demo/nuxt3-demo/package.json index 2d7ef07..2d92366 100644 --- a/components-demo/nuxt3-demo/package.json +++ b/components-demo/nuxt3-demo/package.json @@ -7,7 +7,7 @@ "start": "node .output/server/index.mjs" }, "devDependencies": { - "nuxt3": "latest", + "nuxt": "npm:nuxt3@latest", "ufo": "^0.8.4" }, "dependencies": { diff --git a/components/ember/src/component.ts b/components/ember/src/component.ts index ee350da..edc776b 100644 --- a/components/ember/src/component.ts +++ b/components/ember/src/component.ts @@ -5,8 +5,7 @@ import { tracked } from '@glimmer/tracking'; import type { IconifyIconName } from '@iconify/utils/lib/icon/name'; import { stringToIcon } from '@iconify/utils/lib/icon/name'; import { getIconData } from '@iconify/core/lib/storage/functions'; -import type { FullIconifyIcon } from '@iconify/utils/lib/icon/defaults'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; +import type { IconifyIcon } from '@iconify/utils/lib/icon/defaults'; // API import { loadIcon } from '@iconify/core/lib/api/icons'; @@ -24,7 +23,7 @@ interface CurrentIconData { className: string; // Data if icon has been loaded - data?: FullIconifyIcon; + data?: IconifyIcon; } /** @@ -69,7 +68,7 @@ export class IconifyIconComponent extends Component { this._icon = null; // Render object - return render({ ...defaultIconProps, ...icon }, this.args, ''); + return render(icon, this.args, ''); } // Already loaded diff --git a/components/ember/src/render.ts b/components/ember/src/render.ts index 714eb66..3f77d8a 100644 --- a/components/ember/src/render.ts +++ b/components/ember/src/render.ts @@ -26,7 +26,7 @@ export interface RenderResult { */ export const render = ( // Icon must be validated before calling this function - icon: Required, + icon: IconifyIcon, // Partial properties props: IconifyIconProps, diff --git a/components/react/src/iconify.ts b/components/react/src/iconify.ts index f3277d6..943176e 100644 --- a/components/react/src/iconify.ts +++ b/components/react/src/iconify.ts @@ -20,7 +20,6 @@ import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build'; import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { calculateSize } from '@iconify/utils/lib/svg/size'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; // API import type { @@ -77,6 +76,7 @@ import type { // Render SVG import { render } from './render'; +import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; /** * Export required types @@ -221,7 +221,7 @@ interface InternalIconProps extends IconProps { } interface IconComponentData { - data: Required; + data: IconifyIcon; classes?: string[]; } @@ -290,7 +290,7 @@ class IconComponent extends React.Component< if (changed || state.icon === null) { // Set data if it was changed this._setData({ - data: { ...defaultIconProps, ...icon }, + data: icon, }); } return; @@ -406,7 +406,15 @@ class IconComponent extends React.Component< } // Render icon - return render(icon.data, newProps, props._inline, props._ref); + return render( + { + ...defaultIconProps, + ...icon.data, + }, + newProps, + props._inline, + props._ref + ); } } diff --git a/components/react/src/offline.ts b/components/react/src/offline.ts index 53b93c8..ca64e75 100644 --- a/components/react/src/offline.ts +++ b/components/react/src/offline.ts @@ -26,7 +26,7 @@ export { IconifyIcon, IconifyJSON, IconifyIconSize, IconifyRenderMode }; /** * Storage for icons referred by name */ -const storage: Record> = Object.create(null); +const storage: Record = Object.create(null); /** * Generate icon @@ -37,11 +37,12 @@ function component( ref?: React.ForwardedRef ): JSX.Element { // Split properties + const propsIcon = props.icon; const icon = - typeof props.icon === 'string' - ? storage[props.icon] - : typeof props.icon === 'object' - ? { ...defaultIconProps, ...props.icon } + typeof propsIcon === 'string' + ? storage[propsIcon] + : typeof propsIcon === 'object' + ? propsIcon : null; // Validate icon object @@ -56,7 +57,15 @@ function component( } // Valid icon: render it - return render(icon, props, inline, ref as IconRef); + return render( + { + ...defaultIconProps, + ...icon, + }, + props, + inline, + ref as IconRef + ); } /** @@ -89,7 +98,7 @@ export const InlineIcon = React.forwardRef( * @param data */ export function addIcon(name: string, data: IconifyIcon): void { - storage[name] = { ...defaultIconProps, ...data }; + storage[name] = data; } /** diff --git a/components/svelte/src/functions.ts b/components/svelte/src/functions.ts index 245e19a..13fe6da 100644 --- a/components/svelte/src/functions.ts +++ b/components/svelte/src/functions.ts @@ -217,7 +217,7 @@ interface IconLoadingState { abort: IconifyIconLoaderAbort; } -type IconComponentData = Required | null; +type IconComponentData = IconifyIcon | null; interface IconState { // Last icon name @@ -330,7 +330,15 @@ export function generateIcon( icon: IconComponentData, props: IconProps ): RenderResult | null { - return icon ? render(icon, props) : null; + return icon + ? render( + { + ...defaultIconProps, + ...icon, + }, + props + ) + : null; } /** diff --git a/components/svelte/src/offline-functions.ts b/components/svelte/src/offline-functions.ts index 54a65e8..486f70e 100644 --- a/components/svelte/src/offline-functions.ts +++ b/components/svelte/src/offline-functions.ts @@ -9,7 +9,7 @@ import type { IconProps } from './props'; /** * Storage for icons referred by name */ -const storage: Record> = Object.create(null); +const storage: Record = Object.create(null); /** * Generate icon @@ -32,7 +32,13 @@ export function generateIcon(props: IconProps): RenderResult | null { return null; } - return render(icon, props); + return render( + { + ...defaultIconProps, + ...icon, + }, + props + ); } /** @@ -42,7 +48,7 @@ export function generateIcon(props: IconProps): RenderResult | null { * @param data */ export function addIcon(name: string, data: IconifyIcon): void { - storage[name] = { ...defaultIconProps, ...data }; + storage[name] = data; } /** diff --git a/components/svg-framework/src/render/svg.ts b/components/svg-framework/src/render/svg.ts index b40c976..24181ee 100644 --- a/components/svg-framework/src/render/svg.ts +++ b/components/svg-framework/src/render/svg.ts @@ -1,4 +1,4 @@ -import type { FullIconifyIcon } from '@iconify/utils/lib/icon/defaults'; +import type { IconifyIcon } from '@iconify/utils/lib/icon/defaults'; import { iconToSVG } from '@iconify/utils/lib/svg/build'; import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { iconToHTML } from '@iconify/utils/lib/svg/html'; @@ -17,7 +17,7 @@ import { applyStyle } from './style'; export function renderInlineSVG( element: IconifyElement, props: IconifyElementProps, - iconData: FullIconifyIcon + iconData: IconifyIcon ): IconifyElement { // Create placeholder. Why placeholder? innerHTML setter on SVG does not work in some environments. let span: HTMLSpanElement; diff --git a/components/svg-framework/src/scanner/index.ts b/components/svg-framework/src/scanner/index.ts index 9d5e32f..26bd308 100644 --- a/components/svg-framework/src/scanner/index.ts +++ b/components/svg-framework/src/scanner/index.ts @@ -10,8 +10,8 @@ import { IconifyElementProps, } from './config'; import { scanRootNode } from './find'; -import type { IconifyIconName } from '../iconify'; -import type { FullIconifyIcon } from '@iconify/utils/lib/icon/defaults'; +import type { IconifyIconName, IconifyIcon } from '../iconify'; +import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; import { observe, pauseObservingNode, @@ -56,7 +56,7 @@ export function scanDOM(rootNode?: ObservedNode, addTempNode = false): void { */ interface GetIconResult { status: IconifyElementData['status']; - icon?: FullIconifyIcon; + icon?: IconifyIcon; } function getIcon(icon: IconifyIconName, load: boolean): GetIconResult { const { provider, prefix, name } = icon; @@ -114,7 +114,7 @@ export function scanDOM(rootNode?: ObservedNode, addTempNode = false): void { function render( element: IconifyElement, props: IconifyElementProps, - iconData: FullIconifyIcon + iconData: IconifyIcon ) { if (!paused) { paused = true; @@ -133,7 +133,15 @@ export function scanDOM(rootNode?: ObservedNode, addTempNode = false): void { : null); if (typeof isMask === 'boolean') { - renderBackground(element, props, iconData, isMask); + renderBackground( + element, + props, + { + ...defaultIconProps, + ...iconData, + }, + isMask + ); return; } } diff --git a/components/vue/src/iconify.ts b/components/vue/src/iconify.ts index b411319..74c859a 100644 --- a/components/vue/src/iconify.ts +++ b/components/vue/src/iconify.ts @@ -232,7 +232,7 @@ const emptyIcon = { * Component */ interface IconComponentData { - data: Required; + data: IconifyIcon; classes?: string[]; } @@ -289,7 +289,7 @@ export const Icon = defineComponent({ this._name = ''; this.abortLoading(); return { - data: { ...defaultIconProps, ...icon }, + data: icon, }; } @@ -376,7 +376,13 @@ export const Icon = defineComponent({ } // Render icon - return render(icon.data, newProps); + return render( + { + ...defaultIconProps, + ...icon.data, + }, + newProps + ); }, }); diff --git a/components/vue/src/offline.ts b/components/vue/src/offline.ts index 0fd366e..ea3b20e 100644 --- a/components/vue/src/offline.ts +++ b/components/vue/src/offline.ts @@ -34,7 +34,7 @@ export { IconifyIcon, IconifyJSON, IconifyIconSize, IconifyRenderMode }; /** * Storage for icons referred by name */ -const storage: Record> = Object.create(null); +const storage: Record = Object.create(null); /** * Add icon to storage, allowing to call it by name @@ -43,7 +43,7 @@ const storage: Record> = Object.create(null); * @param data */ export function addIcon(name: string, data: IconifyIcon): void { - storage[name] = { ...defaultIconProps, ...data }; + storage[name] = data; } /** @@ -82,11 +82,12 @@ export const Icon = defineComponent({ const props = this.$attrs; // Check icon - const icon = - typeof props.icon === 'string' - ? storage[props.icon] - : typeof props.icon === 'object' - ? { ...defaultIconProps, ...props.icon } + const propsIcon = props.icon; + const icon: IconifyIcon | null = + typeof propsIcon === 'string' + ? storage[propsIcon] + : typeof propsIcon === 'object' + ? propsIcon : null; // Validate icon object @@ -99,6 +100,12 @@ export const Icon = defineComponent({ } // Valid icon: render it - return render(icon, props); + return render( + { + ...defaultIconProps, + ...icon, + }, + props + ); }, }); diff --git a/components/vue2/src/iconify.ts b/components/vue2/src/iconify.ts index 5b82709..c0dfd28 100644 --- a/components/vue2/src/iconify.ts +++ b/components/vue2/src/iconify.ts @@ -22,7 +22,6 @@ import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build'; import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { calculateSize } from '@iconify/utils/lib/svg/size'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; // API import type { @@ -215,7 +214,6 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') { * Empty icon data, rendered when icon is not available */ const emptyIcon = { - ...defaultIconProps, body: '', }; @@ -223,7 +221,7 @@ const emptyIcon = { * Component */ interface IconComponentData { - data: Required; + data: IconifyIcon; classes?: string[]; } @@ -277,7 +275,7 @@ export const Icon = Vue.extend({ this._name = ''; this.abortLoading(); return { - data: { ...defaultIconProps, ...icon }, + data: icon, }; } diff --git a/components/vue2/src/offline.ts b/components/vue2/src/offline.ts index 3b7bf82..b6712b9 100644 --- a/components/vue2/src/offline.ts +++ b/components/vue2/src/offline.ts @@ -3,7 +3,6 @@ import type { CreateElement, VNode } from 'vue'; import type { ExtendedVue } from 'vue/types/vue'; import type { IconifyIcon, IconifyJSON } from '@iconify/types'; import type { IconifyIconSize } from '@iconify/utils/lib/customisations/defaults'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; import { parseIconSet } from '@iconify/utils/lib/icon-set/parse'; import { quicklyValidateIconSet } from '@iconify/utils/lib/icon-set/validate-basic'; import type { @@ -21,16 +20,12 @@ export { IconifyIconCustomisations, IconifyIconProps, IconProps }; /** * Export types that could be used in component */ -export { - IconifyIcon, - IconifyJSON, - IconifyIconSize, -}; +export { IconifyIcon, IconifyJSON, IconifyIconSize }; /** * Storage for icons referred by name */ -const storage: Record> = Object.create(null); +const storage: Record = Object.create(null); /** * Add icon to storage, allowing to call it by name @@ -39,7 +34,7 @@ const storage: Record> = Object.create(null); * @param data */ export function addIcon(name: string, data: IconifyIcon): void { - storage[name] = {...defaultIconProps, ...data}; + storage[name] = data; } /** @@ -58,11 +53,12 @@ export function addCollection( : prefix !== false && typeof data.prefix === 'string' ? data.prefix + ':' : ''; - quicklyValidateIconSet(data) && parseIconSet(data, (name, icon) => { - if (icon) { - storage[iconPrefix + name] = icon; - } - }); + quicklyValidateIconSet(data) && + parseIconSet(data, (name, icon) => { + if (icon) { + storage[iconPrefix + name] = icon; + } + }); } /** @@ -78,11 +74,12 @@ export const Icon = Vue.extend({ const props = this.$attrs; // Check icon + const propsIcon = props.icon; const icon = - typeof props.icon === 'string' - ? storage[props.icon] - : typeof props.icon === 'object' - ? {...defaultIconProps, ...props.icon} + typeof propsIcon === 'string' + ? storage[propsIcon] + : typeof propsIcon === 'object' + ? propsIcon : null; // Validate icon object diff --git a/components/vue2/src/render.ts b/components/vue2/src/render.ts index b4d0ce9..5520190 100644 --- a/components/vue2/src/render.ts +++ b/components/vue2/src/render.ts @@ -1,14 +1,12 @@ import type _Vue from 'vue'; import type { VNode, VNodeData, RenderContext } from 'vue'; import type { IconifyIcon } from '@iconify/types'; -import { - mergeCustomisations, -} from '@iconify/utils/lib/customisations/merge'; +import { mergeCustomisations } from '@iconify/utils/lib/customisations/merge'; import { flipFromString } from '@iconify/utils/lib/customisations/flip'; import { rotateFromString } from '@iconify/utils/lib/customisations/rotate'; import { iconToSVG } from '@iconify/utils/lib/svg/build'; import { replaceIDs } from '@iconify/utils/lib/svg/id'; -import type { IconifyIconCustomisations, IconProps } from './props'; +import type { IconProps } from './props'; import { defaultExtendedIconCustomisations } from './props'; /** @@ -25,18 +23,17 @@ const svgDefaults: Record = { * Aliases for customisations. * In Vue 'v-' properties are reserved, so v-flip must be renamed */ - const customisationAliases: Record = {}; - ['horizontal', 'vertical'].forEach((prefix) => { - const attr = prefix.slice(0, 1) + 'Flip'; - - // vertical-flip - customisationAliases[prefix + '-flip'] = attr; - // v-flip - customisationAliases[prefix.slice(0, 1) + '-flip'] = attr; - // verticalFlip - customisationAliases[prefix + 'Flip'] = attr; - }); - +const customisationAliases: Record = {}; +['horizontal', 'vertical'].forEach((prefix) => { + const attr = prefix.slice(0, 1) + 'Flip'; + + // vertical-flip + customisationAliases[prefix + '-flip'] = attr; + // v-flip + customisationAliases[prefix.slice(0, 1) + '-flip'] = attr; + // verticalFlip + customisationAliases[prefix + 'Flip'] = attr; +}); /** * Render icon @@ -51,7 +48,7 @@ export const render = ( contextData: VNodeData, // Icon must be validated before calling this function - icon: Required + icon: IconifyIcon ): VNode => { // Split properties const customisations = mergeCustomisations( diff --git a/iconify-icon-demo/nuxt3-demo/nuxt.config.ts b/iconify-icon-demo/nuxt3-demo/nuxt.config.ts index 77c85d8..dd5e368 100644 --- a/iconify-icon-demo/nuxt3-demo/nuxt.config.ts +++ b/iconify-icon-demo/nuxt3-demo/nuxt.config.ts @@ -1,4 +1,4 @@ -import { defineNuxtConfig } from 'nuxt3'; +import { defineNuxtConfig } from 'nuxt'; // https://v3.nuxtjs.org/docs/directory-structure/nuxt.config export default defineNuxtConfig({ diff --git a/iconify-icon-demo/nuxt3-demo/package.json b/iconify-icon-demo/nuxt3-demo/package.json index 0eb180c..cce790e 100644 --- a/iconify-icon-demo/nuxt3-demo/package.json +++ b/iconify-icon-demo/nuxt3-demo/package.json @@ -8,7 +8,7 @@ }, "devDependencies": { "iconify-icon": "workspace:*", - "nuxt3": "latest", + "nuxt": "npm:nuxt3@latest", "ufo": "^0.8.4" } } diff --git a/iconify-icon/icon/src/attributes/icon/index.ts b/iconify-icon/icon/src/attributes/icon/index.ts index a3668f7..1b05973 100644 --- a/iconify-icon/icon/src/attributes/icon/index.ts +++ b/iconify-icon/icon/src/attributes/icon/index.ts @@ -12,7 +12,7 @@ import type { CurrentIconData } from './state'; export type IconOnLoadCallback = ( value: unknown, name: IconifyIconName, - data?: Required | null + data?: IconifyIcon | null ) => void; /** diff --git a/iconify-icon/icon/src/attributes/icon/object.ts b/iconify-icon/icon/src/attributes/icon/object.ts index 36edafb..4faf417 100644 --- a/iconify-icon/icon/src/attributes/icon/object.ts +++ b/iconify-icon/icon/src/attributes/icon/object.ts @@ -1,17 +1,13 @@ import type { IconifyIcon } from '@iconify/types'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; /** * Test icon string */ -export function testIconObject( - value: unknown -): Required | undefined { +export function testIconObject(value: unknown): IconifyIcon | undefined { try { const obj = typeof value === 'string' ? JSON.parse(value) : value; if (typeof obj.body === 'string') { return { - ...defaultIconProps, ...obj, }; } diff --git a/iconify-icon/icon/src/attributes/icon/state.ts b/iconify-icon/icon/src/attributes/icon/state.ts index d0ac30d..fbdd8b8 100644 --- a/iconify-icon/icon/src/attributes/icon/state.ts +++ b/iconify-icon/icon/src/attributes/icon/state.ts @@ -10,7 +10,7 @@ export interface CurrentIconData { value: unknown; // Data, if available. Can be null if icon is missing in API - data?: Required | null; + data?: IconifyIcon | null; // Icon name as object, if `value` is a valid icon name name?: IconifyIconName | null; @@ -20,9 +20,9 @@ export interface CurrentIconData { } /** - * Same as above, if + * Same as above, used if icon is currenly being rendered */ export interface RenderedCurrentIconData extends CurrentIconData { - // Full icon data - data: Required; + // Icon data + data: IconifyIcon; } diff --git a/iconify-icon/icon/src/render/icon.ts b/iconify-icon/icon/src/render/icon.ts index 3e8b94a..7e31d3e 100644 --- a/iconify-icon/icon/src/render/icon.ts +++ b/iconify-icon/icon/src/render/icon.ts @@ -1,3 +1,4 @@ +import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; import { iconToSVG } from '@iconify/utils/lib/svg/build'; import type { RenderedState } from '../state'; import { renderSPAN } from './span'; @@ -25,7 +26,14 @@ export function renderIcon(parent: Element | ShadowRoot, state: RenderedState) { break; default: - node = renderSPAN(renderData, iconData, mode === 'mask'); + node = renderSPAN( + renderData, + { + ...defaultIconProps, + ...iconData, + }, + mode === 'mask' + ); } // Set element diff --git a/iconify-icon/icon/tests/icon-load-api-test.ts b/iconify-icon/icon/tests/icon-load-api-test.ts index 2b9027b..d609adf 100644 --- a/iconify-icon/icon/tests/icon-load-api-test.ts +++ b/iconify-icon/icon/tests/icon-load-api-test.ts @@ -1,5 +1,4 @@ import { fakeAPI, nextPrefix, mockAPIData } from './helpers'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; import { addCollection } from '@iconify/core/lib/storage/functions'; import { parseIconValue } from '../src/attributes/icon/index'; @@ -41,7 +40,6 @@ describe('Testing parseIconValue with API', () => { name, }); expect(data).toEqual({ - ...defaultIconProps, body: '', }); @@ -111,7 +109,6 @@ describe('Testing parseIconValue with API', () => { name, }, data: { - ...defaultIconProps, body: '', }, }); diff --git a/iconify-icon/icon/tests/icon-load-test.ts b/iconify-icon/icon/tests/icon-load-test.ts index 526428d..b4fce77 100644 --- a/iconify-icon/icon/tests/icon-load-test.ts +++ b/iconify-icon/icon/tests/icon-load-test.ts @@ -1,5 +1,4 @@ import { parseIconValue } from '../src/attributes/icon/index'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; describe('Testing parseIconValue without API', () => { it('Instantly loading object', () => { @@ -11,10 +10,7 @@ describe('Testing parseIconValue without API', () => { }); expect(result).toEqual({ value, - data: { - ...defaultIconProps, - ...value, - }, + data: value, }); expect(result.value).toBe(value); }); @@ -29,7 +25,6 @@ describe('Testing parseIconValue without API', () => { expect(result).toEqual({ value, data: { - ...defaultIconProps, body: '', }, }); diff --git a/iconify-icon/icon/tests/icon-object-test.ts b/iconify-icon/icon/tests/icon-object-test.ts index 80d9e23..6d0516d 100644 --- a/iconify-icon/icon/tests/icon-object-test.ts +++ b/iconify-icon/icon/tests/icon-object-test.ts @@ -1,5 +1,4 @@ import { testIconObject } from '../src/attributes/icon/object'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; describe('Testing testIconObject', () => { it('Objects', () => { @@ -8,7 +7,6 @@ describe('Testing testIconObject', () => { body: '', }) ).toEqual({ - ...defaultIconProps, body: '', }); @@ -19,7 +17,6 @@ describe('Testing testIconObject', () => { height: '32', }) ).toEqual({ - ...defaultIconProps, body: '', width: 24, // Validation is simple, this will fail during render @@ -50,7 +47,6 @@ describe('Testing testIconObject', () => { }) ) ).toEqual({ - ...defaultIconProps, body: '', }); diff --git a/packages/core/src/api/icons.ts b/packages/core/src/api/icons.ts index 861914c..24be773 100644 --- a/packages/core/src/api/icons.ts +++ b/packages/core/src/api/icons.ts @@ -10,6 +10,7 @@ import { allowSimpleNames, getIconData } from '../storage/functions'; import { sendAPIQuery } from './query'; import { storeInBrowserStorage } from '../browser-storage/store'; import type { IconStorageWithAPI } from './types'; +import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; // Empty abort callback for loadIcons() function emptyCallback(): void { @@ -249,7 +250,7 @@ export const loadIcons: IconifyLoadIcons = ( }; /** - * Cache for loadIcon promises + * Load one icon using Promise */ export const loadIcon = ( icon: IconifyIconName | string @@ -261,6 +262,7 @@ export const loadIcon = ( const data = getIconData(iconObj); if (data) { fulfill({ + ...defaultIconProps, ...data, }); return; diff --git a/packages/core/src/storage/functions.ts b/packages/core/src/storage/functions.ts index 1a0e50f..14a34c9 100644 --- a/packages/core/src/storage/functions.ts +++ b/packages/core/src/storage/functions.ts @@ -1,5 +1,5 @@ import type { IconifyJSON, IconifyIcon } from '@iconify/types'; -import type { FullIconifyIcon } from '@iconify/utils/lib/icon/defaults'; +import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; import { parseIconSet } from '@iconify/utils/lib/icon-set/parse'; import { quicklyValidateIconSet } from '@iconify/utils/lib/icon-set/validate-basic'; import type { IconifyIconName } from '@iconify/utils/lib/icon/name'; @@ -53,25 +53,24 @@ export function allowSimpleNames(allow?: boolean): boolean { * Get icon data * * Returns: - * - Required on success, object directly from storage so don't modify it + * - IconifyIcon on success, object directly from storage so don't modify it * - null if icon is marked as missing (returned in `not_found` property from API, so don't bother sending API requests) * - undefined if icon is missing */ export function getIconData( name: string | IconifyIconName -): FullIconifyIcon | null | undefined { +): IconifyIcon | null | undefined { const icon = typeof name === 'string' ? stringToIcon(name, true, simpleNames) : name; - if (!icon) { - return; + if (icon) { + const storage = getStorage(icon.provider, icon.prefix); + const iconName = icon.name; + return ( + storage.icons[iconName] || + (storage.missing.has(iconName) ? null : void 0) + ); } - const storage = getStorage(icon.provider, icon.prefix); - const iconName = icon.name; - return ( - storage.icons[iconName] || - (storage.missing.has(iconName) ? null : void 0) - ); } /** @@ -143,10 +142,16 @@ export function addCollection(data: IconifyJSON, provider?: string): boolean { export function iconExists(name: string): boolean { return !!getIconData(name); } + /** - * Get icon + * Get full icon */ export function getIcon(name: string): Required | null { const result = getIconData(name); - return result ? { ...result } : null; + return result + ? { + ...defaultIconProps, + ...result, + } + : null; } diff --git a/packages/core/src/storage/storage.ts b/packages/core/src/storage/storage.ts index d8712f2..c41cc3b 100644 --- a/packages/core/src/storage/storage.ts +++ b/packages/core/src/storage/storage.ts @@ -1,13 +1,11 @@ import type { IconifyJSON, IconifyIcon } from '@iconify/types'; -import type { FullIconifyIcon } from '@iconify/utils/lib/icon/defaults'; -import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; import { parseIconSet } from '@iconify/utils/lib/icon-set/parse'; import { quicklyValidateIconSet } from '@iconify/utils/lib/icon-set/validate-basic'; /** * List of icons */ -type IconRecords = Record; +type IconRecords = Record; /** * Storage type @@ -72,10 +70,7 @@ export function addIconSet(storage: IconStorage, data: IconifyJSON): string[] { return parseIconSet(data, (name: string, icon: IconifyIcon | null) => { if (icon) { - storage.icons[name] = { - ...defaultIconProps, - ...icon, - }; + storage.icons[name] = icon; } else { storage.missing.add(name); } @@ -92,11 +87,8 @@ export function addIconToStorage( ): boolean { try { if (typeof icon.body === 'string') { - // Freeze icon to make sure it will not be modified - storage.icons[name] = Object.freeze({ - ...defaultIconProps, - ...icon, - }); + // Make a copy of object to make sure it will not be not modified + storage.icons[name] = { ...icon }; return true; } } catch (err) { diff --git a/packages/core/tests/storage/storage-functions-test.ts b/packages/core/tests/storage/storage-functions-test.ts index 93710fa..7a34baf 100644 --- a/packages/core/tests/storage/storage-functions-test.ts +++ b/packages/core/tests/storage/storage-functions-test.ts @@ -29,8 +29,8 @@ describe('Testing IconifyStorageFunctions', () => { // Empty expect(iconExists(testName)).toBe(false); - expect(getIcon(testName)).toBeNull(); expect(getIconData(testName)).toBeUndefined(); + expect(getIcon(testName)).toBeNull(); expect(listIcons(provider)).toEqual([]); // Add and test one icon @@ -43,11 +43,13 @@ describe('Testing IconifyStorageFunctions', () => { expect(listIcons(provider)).toEqual([testName]); let expected = { - ...defaultIconProps, body: '', }; expect(getIconData(testName)).toEqual(expected); - expect(getIcon(testName)).toEqual(expected); + expect(getIcon(testName)).toEqual({ + ...defaultIconProps, + ...expected, + }); // Add icon set const prefix = 'prefix' + (count++).toString(); @@ -65,11 +67,13 @@ describe('Testing IconifyStorageFunctions', () => { // Test 'home' icon expect(iconExists(`${prefix}:home`)).toBe(true); expected = { - ...defaultIconProps, body: '', }; expect(getIconData(`${prefix}:home`)).toEqual(expected); - expect(getIcon(`${prefix}:home`)).toEqual(expected); + expect(getIcon(`${prefix}:home`)).toEqual({ + ...defaultIconProps, + ...expected, + }); // Test 'missing' icon expect(iconExists(`${prefix}:missing`)).toBe(false); @@ -87,8 +91,8 @@ describe('Testing IconifyStorageFunctions', () => { // Empty expect(iconExists(testName)).toBe(false); - expect(getIcon(testName)).toBeNull(); expect(getIconData(testName)).toBeUndefined(); + expect(getIcon(testName)).toBeNull(); // Add and test one icon (icon should not be added) expect( @@ -164,36 +168,42 @@ describe('Testing IconifyStorageFunctions', () => { name = name1; expect(iconExists(name)).toBe(true); let expected = { - ...defaultIconProps, body: '', }; - expect(getIcon(name)).toEqual(expected); expect(getIconData(name)).toEqual(expected); + expect(getIcon(name)).toEqual({ + ...defaultIconProps, + ...expected, + }); // Test prefixed icon, using ':' separator name = `${prefix2}:${name2}`; expect(listIcons('', prefix2)).toEqual([name]); expect(iconExists(name)).toBe(true); expected = { - ...defaultIconProps, body: '', }; - expect(getIcon(name)).toEqual(expected); expect(getIconData(name)).toEqual(expected); + expect(getIcon(name)).toEqual({ + ...defaultIconProps, + ...expected, + }); // Test prefixed icon, using '-' separator name = `${prefix2}-${name2}`; expect(iconExists(name)).toBe(true); expected = { - ...defaultIconProps, body: '', }; - expect(getIcon(name)).toEqual(expected); expect(getIconData(name)).toEqual(expected); + expect(getIcon(name)).toEqual({ + ...defaultIconProps, + ...expected, + }); // Test missing icon: should not exist because without provider missing icon cannot be added expect(iconExists(missing)).toBe(false); - expect(getIcon(missing)).toBeNull(); expect(getIconData(missing)).toBeUndefined(); + expect(getIcon(missing)).toBeNull(); }); }); diff --git a/packages/core/tests/storage/storage-test.ts b/packages/core/tests/storage/storage-test.ts index 17addc8..b4294ce 100644 --- a/packages/core/tests/storage/storage-test.ts +++ b/packages/core/tests/storage/storage-test.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ +import type { IconifyIcon } from '@iconify/types'; import { newStorage, addIconToStorage, @@ -7,10 +8,6 @@ import { getStorage, listIcons, } from '../../lib/storage/storage'; -import type { - IconifyIcon, - FullIconifyIcon, -} from '@iconify/utils/lib/icon/defaults'; describe('Testing storage', () => { it('Adding icon', () => { @@ -57,37 +54,18 @@ describe('Testing storage', () => { expect(iconExists(storage, 'not-really-missing')).toBe(true); // Test getIcon - let expected: FullIconifyIcon = { + let expected: IconifyIcon = { body: '', width: 20, height: 16, - top: 0, - left: 0, - hFlip: false, - vFlip: false, - rotate: 0, }; const icon = storage.icons['test']; expect(icon).toEqual(expected); - // Test icon mutation - let thrown = false; - try { - // @ts-ignore - icon.width = 12; - } catch (err) { - thrown = true; - } - expect(thrown).toBe(true); - expected = { body: '', width: 24, height: 24, - top: 0, - left: 0, - hFlip: false, - vFlip: false, rotate: 1, }; expect(storage.icons['constructor']).toEqual(expected); @@ -125,26 +103,16 @@ describe('Testing storage', () => { expect(iconExists(storage, 'missing')).toBe(false); // Test getIcon - let expected: FullIconifyIcon = { + let expected: IconifyIcon = { body: '', width: 20, height: 24, - top: 0, - left: 0, - hFlip: false, - vFlip: false, - rotate: 0, }; expect(storage.icons['icon1']).toEqual(expected); expected = { body: '', width: 24, height: 24, - top: 0, - left: 0, - hFlip: false, - vFlip: false, - rotate: 0, }; expect(storage.icons['icon2']).toEqual(expected); }); @@ -179,15 +147,10 @@ describe('Testing storage', () => { ]); // Test icon - let expected: FullIconifyIcon = { + let expected: IconifyIcon = { body: iconBody, width: 128, height: 128, - top: 0, - left: 0, - hFlip: false, - vFlip: false, - rotate: 0, }; expect(storage.icons['16-chevron-left']).toEqual(expected); @@ -196,11 +159,7 @@ describe('Testing storage', () => { body: iconBody, width: 128, height: 128, - top: 0, - left: 0, hFlip: true, - vFlip: false, - rotate: 0, }; expect(storage.icons['16-chevron-right']).toEqual(expected); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 65c5703..031cb8c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -107,12 +107,12 @@ importers: components-demo/nuxt3-demo: specifiers: '@iconify/vue': workspace:* - nuxt3: latest + nuxt: npm:nuxt3@latest ufo: ^0.8.4 dependencies: '@iconify/vue': link:../../components/vue devDependencies: - nuxt3: 3.0.0-rc.4-27605536.8c2c80e_5cbeqmovjazlwrjcfaylsl5bey + nuxt: /nuxt3/3.0.0-rc.4-27611167.a41644e_5cbeqmovjazlwrjcfaylsl5bey ufo: 0.8.4 components-demo/react-demo: @@ -691,11 +691,11 @@ importers: iconify-icon-demo/nuxt3-demo: specifiers: iconify-icon: workspace:* - nuxt3: latest + nuxt: npm:nuxt3@latest ufo: ^0.8.4 devDependencies: iconify-icon: link:../../iconify-icon/icon - nuxt3: 3.0.0-rc.4-27605536.8c2c80e + nuxt: /nuxt3/3.0.0-rc.4-27611167.a41644e ufo: 0.8.4 iconify-icon-demo/react-demo: @@ -943,7 +943,7 @@ importers: eslint-plugin-jasmine: 4.1.3 jasmine: 4.2.1 jest: 28.0.0-alpha.11_@types+node@17.0.45 - ts-jest: 28.0.0-next.3_wacmy45vuvn6xci2xoa2yuot5q + ts-jest: 28.0.0-next.3_siglip3kymrenbe7xdfdfpitau tsup: 5.12.9_typescript@4.7.4 packages/core: @@ -1032,7 +1032,7 @@ importers: eslint-plugin-prettier: 4.0.0_xu6ewijrtliw5q5lksq5uixwby jest: 28.0.0-alpha.11_jbmz3vlfopghb5mdasddsdxfzq rimraf: 3.0.2 - ts-jest: 28.0.0-next.3_siglip3kymrenbe7xdfdfpitau + ts-jest: 28.0.0-next.3_wacmy45vuvn6xci2xoa2yuot5q ts-node: 10.8.1_qiyc72axg2v44xl4yovan2v55u typescript: 4.7.4 unbuild: 0.7.4 @@ -3714,11 +3714,11 @@ packages: resolution: {integrity: sha512-YBI/6o2EBz02tdEJRBK8xkt3zvOFOWlLBf7WKYGBsSYSRtjjgrqPe2skp6VLLmKx5WbHHDNcW+6oACaurxGzeA==} dev: true - /@nuxt/kit-edge/3.0.0-rc.4-27605536.8c2c80e: - resolution: {integrity: sha512-Fu9ygT3Gi5zbthzZC5PVzaDhVUxLunF1mgfF9b7RoHaO+UoQSWI7AptRwx2jxkUHpftLZjELtDV6MW96xZiWqg==} + /@nuxt/kit-edge/3.0.0-rc.4-27611167.a41644e: + resolution: {integrity: sha512-T9rWEkGG4XmVt/5+oam1aSmX8W7kU2FnXrSl4rTlYT09/po0cNbmvDhUQWqt5LUkJMjPsZB5j+87pq2/m0RUEg==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0} dependencies: - '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.4-27605536.8c2c80e + '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.4-27611167.a41644e c12: 0.2.7 consola: 2.15.3 defu: 6.0.0 @@ -3744,11 +3744,11 @@ packages: - webpack dev: true - /@nuxt/kit-edge/3.0.0-rc.4-27605536.8c2c80e_5cbeqmovjazlwrjcfaylsl5bey: - resolution: {integrity: sha512-Fu9ygT3Gi5zbthzZC5PVzaDhVUxLunF1mgfF9b7RoHaO+UoQSWI7AptRwx2jxkUHpftLZjELtDV6MW96xZiWqg==} + /@nuxt/kit-edge/3.0.0-rc.4-27611167.a41644e_5cbeqmovjazlwrjcfaylsl5bey: + resolution: {integrity: sha512-T9rWEkGG4XmVt/5+oam1aSmX8W7kU2FnXrSl4rTlYT09/po0cNbmvDhUQWqt5LUkJMjPsZB5j+87pq2/m0RUEg==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0} dependencies: - '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.4-27605536.8c2c80e_5cbeqmovjazlwrjcfaylsl5bey + '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.4-27611167.a41644e_5cbeqmovjazlwrjcfaylsl5bey c12: 0.2.7 consola: 2.15.3 defu: 6.0.0 @@ -3834,8 +3834,8 @@ packages: - webpack dev: true - /@nuxt/schema-edge/3.0.0-rc.4-27605536.8c2c80e: - resolution: {integrity: sha512-KOFpjN2efx9lXj84kSHhJV/XWJ8n0zztnJjjmEY3RhgBTd7mYtdI7BsYPtZ30Tz5vJGMlHrIGkLZW6c+IYAKzw==} + /@nuxt/schema-edge/3.0.0-rc.4-27611167.a41644e: + resolution: {integrity: sha512-FaM88rk9lvgaTUe+YpiNbMDg/iEb98Lejo33B+pHuPFyrZWR+hAFOL27LeEIAGBZk3xQaDfXRU6TYKEPE5iGsQ==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0} dependencies: c12: 0.2.7 @@ -3855,8 +3855,8 @@ packages: - webpack dev: true - /@nuxt/schema-edge/3.0.0-rc.4-27605536.8c2c80e_5cbeqmovjazlwrjcfaylsl5bey: - resolution: {integrity: sha512-KOFpjN2efx9lXj84kSHhJV/XWJ8n0zztnJjjmEY3RhgBTd7mYtdI7BsYPtZ30Tz5vJGMlHrIGkLZW6c+IYAKzw==} + /@nuxt/schema-edge/3.0.0-rc.4-27611167.a41644e_5cbeqmovjazlwrjcfaylsl5bey: + resolution: {integrity: sha512-FaM88rk9lvgaTUe+YpiNbMDg/iEb98Lejo33B+pHuPFyrZWR+hAFOL27LeEIAGBZk3xQaDfXRU6TYKEPE5iGsQ==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0} dependencies: c12: 0.2.7 @@ -3986,13 +3986,13 @@ packages: resolution: {integrity: sha512-ejiWi7RJfUp71K5IRpfrhoiZcvxhn1K+YH5mWdwwCT7jeQyE+Ok6WdFMpSg4LYy8YsVw6XHr5I+g23OCebc24w==} dev: true - /@nuxt/vite-builder-edge/3.0.0-rc.4-27605536.8c2c80e_vue@3.2.37: - resolution: {integrity: sha512-iQkb9iz+X5QdSpQwawaf2vCXFSvY+VwNXxh5irAiJ91eWh4hwq1QlkB4F4aXEL20oOy72tYP/Pyd76j/ZDfZGQ==} + /@nuxt/vite-builder-edge/3.0.0-rc.4-27611167.a41644e_vue@3.2.37: + resolution: {integrity: sha512-h5omNouNcLIL0D/Q41JQYMimiB17oxmV9ZGHKXjj2VcYTzNyWsSlvS6h5AWu19m1N4Ctp5uS5amCGA26F/2E5A==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0} peerDependencies: vue: ^3.2.37 dependencies: - '@nuxt/kit': /@nuxt/kit-edge/3.0.0-rc.4-27605536.8c2c80e_5cbeqmovjazlwrjcfaylsl5bey + '@nuxt/kit': /@nuxt/kit-edge/3.0.0-rc.4-27611167.a41644e_5cbeqmovjazlwrjcfaylsl5bey '@rollup/plugin-replace': 4.0.0_rollup@2.75.7 '@vitejs/plugin-vue': 2.3.3_vite@2.9.12+vue@3.2.37 '@vitejs/plugin-vue-jsx': 1.3.10 @@ -16826,25 +16826,25 @@ packages: engines: {node: '>=0.10.0'} dev: true - /nuxi-edge/3.0.0-rc.4-27605536.8c2c80e: - resolution: {integrity: sha512-z2+uUI5DeG3/OT+MN14kLIty+XMBYe2vj+33pMBC7dtv04akN7eYD9LEclqg5BdDc+SgOMZ+g3KKEvl9mQdT1Q==} + /nuxi-edge/3.0.0-rc.4-27611167.a41644e: + resolution: {integrity: sha512-Lz+7WKTj3ES9T5EKobt2DZyuVqUYWpmnMqnGfOXWJbV+9aMTc4jhZOfp4Z57cDEOGHr7C06OBjHoWAHQY9D7Xw==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0} hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true - /nuxt3/3.0.0-rc.4-27605536.8c2c80e: - resolution: {integrity: sha512-/flVMCyPraeozADNbPsOlJfjOUGlUXdPO4eycCyw6uQHz/RQBDfKDS2RGHa6g51Ef5h7bJWhnNc/o1zCgWzedQ==} + /nuxt3/3.0.0-rc.4-27611167.a41644e: + resolution: {integrity: sha512-+gVgU9IUxgvQws4iyoMbBaSplNVa7nwURL18IZybvhubvNepgXzxmcnfWfwjExgSi0tNR5aZ+VICfXpGrPYBNA==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0} hasBin: true dependencies: '@nuxt/devalue': 2.0.0 - '@nuxt/kit': /@nuxt/kit-edge/3.0.0-rc.4-27605536.8c2c80e - '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.4-27605536.8c2c80e + '@nuxt/kit': /@nuxt/kit-edge/3.0.0-rc.4-27611167.a41644e + '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.4-27611167.a41644e '@nuxt/telemetry': 2.1.3 '@nuxt/ui-templates': 0.1.1 - '@nuxt/vite-builder': /@nuxt/vite-builder-edge/3.0.0-rc.4-27605536.8c2c80e_vue@3.2.37 + '@nuxt/vite-builder': /@nuxt/vite-builder-edge/3.0.0-rc.4-27611167.a41644e_vue@3.2.37 '@vue/reactivity': 3.2.37 '@vue/shared': 3.2.37 '@vueuse/head': 0.7.6_vue@3.2.37 @@ -16862,7 +16862,7 @@ packages: magic-string: 0.26.2 mlly: 0.5.3 nitropack: 0.4.8 - nuxi: /nuxi-edge/3.0.0-rc.4-27605536.8c2c80e + nuxi: /nuxi-edge/3.0.0-rc.4-27611167.a41644e ohash: 0.1.0 ohmyfetch: 0.4.18 pathe: 0.3.0 @@ -16892,17 +16892,17 @@ packages: - webpack dev: true - /nuxt3/3.0.0-rc.4-27605536.8c2c80e_5cbeqmovjazlwrjcfaylsl5bey: - resolution: {integrity: sha512-/flVMCyPraeozADNbPsOlJfjOUGlUXdPO4eycCyw6uQHz/RQBDfKDS2RGHa6g51Ef5h7bJWhnNc/o1zCgWzedQ==} + /nuxt3/3.0.0-rc.4-27611167.a41644e_5cbeqmovjazlwrjcfaylsl5bey: + resolution: {integrity: sha512-+gVgU9IUxgvQws4iyoMbBaSplNVa7nwURL18IZybvhubvNepgXzxmcnfWfwjExgSi0tNR5aZ+VICfXpGrPYBNA==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0} hasBin: true dependencies: '@nuxt/devalue': 2.0.0 - '@nuxt/kit': /@nuxt/kit-edge/3.0.0-rc.4-27605536.8c2c80e_5cbeqmovjazlwrjcfaylsl5bey - '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.4-27605536.8c2c80e_5cbeqmovjazlwrjcfaylsl5bey + '@nuxt/kit': /@nuxt/kit-edge/3.0.0-rc.4-27611167.a41644e_5cbeqmovjazlwrjcfaylsl5bey + '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.4-27611167.a41644e_5cbeqmovjazlwrjcfaylsl5bey '@nuxt/telemetry': 2.1.3_5cbeqmovjazlwrjcfaylsl5bey '@nuxt/ui-templates': 0.1.1 - '@nuxt/vite-builder': /@nuxt/vite-builder-edge/3.0.0-rc.4-27605536.8c2c80e_vue@3.2.37 + '@nuxt/vite-builder': /@nuxt/vite-builder-edge/3.0.0-rc.4-27611167.a41644e_vue@3.2.37 '@vue/reactivity': 3.2.37 '@vue/shared': 3.2.37 '@vueuse/head': 0.7.6_vue@3.2.37 @@ -16920,7 +16920,7 @@ packages: magic-string: 0.26.2 mlly: 0.5.3 nitropack: 0.4.8_vite@2.9.12 - nuxi: /nuxi-edge/3.0.0-rc.4-27605536.8c2c80e + nuxi: /nuxi-edge/3.0.0-rc.4-27611167.a41644e ohash: 0.1.0 ohmyfetch: 0.4.18 pathe: 0.3.0 @@ -20899,7 +20899,7 @@ packages: bs-logger: 0.2.6 esbuild: 0.14.48 fast-json-stable-stringify: 2.1.0 - jest: 28.0.0-alpha.11_jbmz3vlfopghb5mdasddsdxfzq + jest: 28.0.0-alpha.11_@types+node@17.0.45 jest-util: 28.1.1 json5: 2.2.1 lodash.memoize: 4.1.2 @@ -20934,7 +20934,7 @@ packages: bs-logger: 0.2.6 esbuild: 0.14.48 fast-json-stable-stringify: 2.1.0 - jest: 28.0.0-alpha.11_@types+node@17.0.45 + jest: 28.0.0-alpha.11_jbmz3vlfopghb5mdasddsdxfzq jest-util: 28.1.1 json5: 2.2.1 lodash.memoize: 4.1.2