diff --git a/apps/client/src/pages/builder/sidebars/left/sections/custom/section.tsx b/apps/client/src/pages/builder/sidebars/left/sections/custom/section.tsx index b8e1c025f..dfe556f40 100644 --- a/apps/client/src/pages/builder/sidebars/left/sections/custom/section.tsx +++ b/apps/client/src/pages/builder/sidebars/left/sections/custom/section.tsx @@ -91,7 +91,7 @@ export const CustomFieldsSection = ({ className }: Props) => { const onChangeCustomField = (field: ICustomField) => { const index = customFields.findIndex((item) => item.id === field.id); - const newCustomFields = JSON.parse(JSON.stringify(customFields)) as ICustomField[]; + const newCustomFields = structuredClone(customFields); newCustomFields[index] = field; setValue("basics.customFields", newCustomFields); diff --git a/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx b/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx index bdbea79d2..443077c4d 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx @@ -163,7 +163,7 @@ export const LayoutSection = () => { }; const onAddPage = () => { - const layoutCopy = JSON.parse(JSON.stringify(layout)) as string[][][]; + const layoutCopy = structuredClone(layout); layoutCopy.push([[], []]); @@ -171,7 +171,7 @@ export const LayoutSection = () => { }; const onRemovePage = (page: number) => { - const layoutCopy = JSON.parse(JSON.stringify(layout)) as string[][][]; + const layoutCopy = structuredClone(layout); layoutCopy[0][0].push(...layoutCopy[page][0]); // Main layoutCopy[0][1].push(...layoutCopy[page][1]); // Sidebar @@ -182,7 +182,7 @@ export const LayoutSection = () => { }; const onResetLayout = () => { - const layoutCopy = JSON.parse(JSON.stringify(defaultMetadata.layout)) as string[][][]; + const layoutCopy = structuredClone(defaultMetadata.layout); // Loop through all pages and columns, and get any sections that start with "custom." // These should be appended to the first page of the new layout. diff --git a/apps/client/src/stores/resume.ts b/apps/client/src/stores/resume.ts index 1dfc1a916..7bdcb7785 100644 --- a/apps/client/src/stores/resume.ts +++ b/apps/client/src/stores/resume.ts @@ -35,7 +35,7 @@ export const useResumeStore = create()( state.resume.data = _set(state.resume.data, path, value); } - void debouncedUpdateResume(JSON.parse(JSON.stringify(state.resume))); + void debouncedUpdateResume(structuredClone(state.resume)); }); }, addSection: () => { @@ -51,7 +51,7 @@ export const useResumeStore = create()( state.resume.data.metadata.layout[lastPageIndex][0].push(`custom.${section.id}`); state.resume.data = _set(state.resume.data, `sections.custom.${section.id}`, section); - void debouncedUpdateResume(JSON.parse(JSON.stringify(state.resume))); + void debouncedUpdateResume(structuredClone(state.resume)); }); }, removeSection: (sectionId: SectionKey) => { @@ -63,7 +63,7 @@ export const useResumeStore = create()( // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete state.resume.data.sections.custom[id]; - void debouncedUpdateResume(JSON.parse(JSON.stringify(state.resume))); + void debouncedUpdateResume(structuredClone(state.resume)); }); } }, diff --git a/libs/parser/src/json-resume/index.ts b/libs/parser/src/json-resume/index.ts index 054bbb910..1323b0c4d 100644 --- a/libs/parser/src/json-resume/index.ts +++ b/libs/parser/src/json-resume/index.ts @@ -12,7 +12,6 @@ import { defaultResumeData, defaultSkill, defaultVolunteer, - ResumeData, } from "@reactive-resume/schema"; import { Json } from "@reactive-resume/utils"; import { Schema } from "zod"; @@ -58,7 +57,7 @@ export class JsonResumeParser implements Parser { } convert(data: JsonResume) { - const result = JSON.parse(JSON.stringify(defaultResumeData)) as ResumeData; + const result = structuredClone(defaultResumeData); // Basics result.basics.name = data.basics?.name ?? ""; diff --git a/libs/parser/src/linkedin/index.ts b/libs/parser/src/linkedin/index.ts index cf0044e7b..844fc6909 100644 --- a/libs/parser/src/linkedin/index.ts +++ b/libs/parser/src/linkedin/index.ts @@ -8,7 +8,6 @@ import { defaultProject, defaultResumeData, defaultSkill, - ResumeData, resumeDataSchema, } from "@reactive-resume/schema"; import { extractUrl, Json, parseArrayLikeCSVEntry, parseCSV } from "@reactive-resume/utils"; @@ -58,7 +57,7 @@ export class LinkedInParser implements Parser { } convert(data: LinkedIn) { - const result = JSON.parse(JSON.stringify(defaultResumeData)) as ResumeData; + const result = structuredClone(defaultResumeData); // Profile if (data.Profile && data.Profile.length > 0) { diff --git a/libs/parser/src/reactive-resume-v3/index.ts b/libs/parser/src/reactive-resume-v3/index.ts index 166f06690..f49c2957d 100644 --- a/libs/parser/src/reactive-resume-v3/index.ts +++ b/libs/parser/src/reactive-resume-v3/index.ts @@ -14,7 +14,6 @@ import { defaultResumeData, defaultSkill, defaultVolunteer, - ResumeData, } from "@reactive-resume/schema"; import { isUrl, Json } from "@reactive-resume/utils"; import { Schema } from "zod"; @@ -60,7 +59,7 @@ export class ReactiveResumeV3Parser implements Parser { } convert(data: ReactiveResumeV3) { - const result = JSON.parse(JSON.stringify(defaultResumeData)) as ResumeData; + const result = structuredClone(defaultResumeData); // Basics result.basics.name = data.basics.name ?? ""; diff --git a/libs/utils/src/namespaces/array.ts b/libs/utils/src/namespaces/array.ts index 872bee5aa..e8874b1fb 100644 --- a/libs/utils/src/namespaces/array.ts +++ b/libs/utils/src/namespaces/array.ts @@ -34,7 +34,7 @@ export const moveItemInLayout = ( ): string[][][] => { try { // Create a deep copy of the layout to avoid mutating the original array - const newLayout = JSON.parse(JSON.stringify(layout)) as string[][][]; + const newLayout = structuredClone(layout); // Get the item from the current location const item = newLayout[current.page][current.column][current.section]; diff --git a/libs/utils/src/namespaces/tests/array.test.ts b/libs/utils/src/namespaces/tests/array.test.ts index 4d7246477..59fbc107e 100644 --- a/libs/utils/src/namespaces/tests/array.test.ts +++ b/libs/utils/src/namespaces/tests/array.test.ts @@ -84,7 +84,7 @@ describe("moveItemInLayout", () => { [["item1"], ["item2"]], [["item3"], ["item4"]], ]; - const layoutCopy = JSON.parse(JSON.stringify(layout)); + const layoutCopy = structuredClone(layout); const current = { page: 0, column: 1, section: 0 }; const target = { page: 1, column: 0, section: 1 };