Skip to content

Commit a18b9a0

Browse files
committed
fix: content comparison
1 parent 13f5990 commit a18b9a0

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

src/app/src/utils/database.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function isEqual(document1: DatabasePageItem, document2: DatabasePageItem
3535
}
3636
}
3737

38-
if (JSON.stringify(documentData1) !== JSON.stringify(documentData2)) {
38+
if (!isDeepEqual(refineDocumentData(documentData1), refineDocumentData(documentData2))) {
3939
return false
4040
}
4141

@@ -49,3 +49,34 @@ export function isEqual(document1: DatabasePageItem, document2: DatabasePageItem
4949

5050
return true
5151
}
52+
53+
function refineDocumentData(doc: Record<string, unknown>) {
54+
if (doc.seo) {
55+
const seo = doc.seo as Record<string, unknown>
56+
doc.seo = {
57+
...seo,
58+
title: seo.title || doc.title,
59+
description: seo.description || doc.description,
60+
}
61+
}
62+
// documents with same id are being compared, so it is safe to remove `path` and `__hash__`
63+
Reflect.deleteProperty(doc, '__hash__')
64+
Reflect.deleteProperty(doc, 'path')
65+
return doc
66+
}
67+
68+
function isDeepEqual(obj1: Record<string, unknown>, obj2: Record<string, unknown>) {
69+
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return obj1 === obj2
70+
71+
const keys1 = Object.keys(obj1).filter(k => obj1[k] != null)
72+
const keys2 = Object.keys(obj2).filter(k => obj2[k] != null)
73+
74+
if (keys1.length !== keys2.length) return false
75+
76+
for (const key of keys1) {
77+
if (!keys2.includes(key)) continue // Ignore missing null/undefined fields
78+
if (!isDeepEqual(obj1[key] as Record<string, unknown>, obj2[key] as Record<string, unknown>)) return false
79+
}
80+
81+
return true
82+
}

src/app/src/utils/draft.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { DatabaseItem, MediaItem, DatabasePageItem, DraftItem, BaseItem, Co
22
import { DraftStatus, ContentFileExtension, TreeRootId } from '../types'
33
import { isEqual } from './database'
44
import { studioFlags } from '../composables/useStudio'
5-
import { generateContentFromDocument } from './content'
5+
import { generateContentFromDocument, generateDocumentFromContent } from './content'
66
import { fromBase64ToUTF8 } from '../utils/string'
77

88
export async function checkConflict(draftItem: DraftItem<DatabaseItem | MediaItem>): Promise<ContentConflict | undefined> {
@@ -28,6 +28,11 @@ export async function checkConflict(draftItem: DraftItem<DatabaseItem | MediaIte
2828

2929
const localContent = await generateContentFromDocument(draftItem.original as DatabaseItem) as string
3030
const githubContent = fromBase64ToUTF8(draftItem.githubFile.content)
31+
const githubDocument = await generateDocumentFromContent(draftItem.id, githubContent) as DatabaseItem
32+
33+
if (isEqual(draftItem.original as DatabasePageItem, githubDocument as DatabasePageItem)) {
34+
return
35+
}
3136

3237
if (localContent.trim() === githubContent.trim()) {
3338
return

0 commit comments

Comments
 (0)