Update database schema and synchronization logic
- Add `useEffect` in `ScribeLeftBar` for handling book state changes. - Extend `BooksSyncContext` with new properties and stricter typings. - Refine `Repositories` to include `lastUpdate` handling for synchronization processes. - Add comprehensive `fetchComplete*` repository methods for retrieving entity-specific sync data. - Enhance offline logic for chapters, characters, locations, and world synchronization. - Improve error handling across IPC handlers and repositories.
This commit is contained in:
@@ -109,4 +109,232 @@ export interface SyncedGuideLine {
|
||||
|
||||
export interface SyncedAIGuideLine {
|
||||
lastUpdate: number;
|
||||
}
|
||||
|
||||
export interface BookSyncCompare {
|
||||
id: string;
|
||||
chapters: string[];
|
||||
chapterContents: string[];
|
||||
chapterInfos: string[];
|
||||
characters: string[];
|
||||
characterAttributes: string[];
|
||||
locations: string[];
|
||||
locationElements: string[];
|
||||
locationSubElements: string[];
|
||||
worlds: string[];
|
||||
worldElements: string[];
|
||||
incidents: string[];
|
||||
plotPoints: string[];
|
||||
issues: string[];
|
||||
actSummaries: string[];
|
||||
guideLine: boolean;
|
||||
aiGuideLine: boolean;
|
||||
}
|
||||
|
||||
export function compareBookSyncs(newerBook: SyncedBook, olderBook: SyncedBook): BookSyncCompare | null {
|
||||
const changedChapterIds: string[] = [];
|
||||
const changedChapterContentIds: string[] = [];
|
||||
const changedChapterInfoIds: string[] = [];
|
||||
const changedCharacterIds: string[] = [];
|
||||
const changedCharacterAttributeIds: string[] = [];
|
||||
const changedLocationIds: string[] = [];
|
||||
const changedLocationElementIds: string[] = [];
|
||||
const changedLocationSubElementIds: string[] = [];
|
||||
const changedWorldIds: string[] = [];
|
||||
const changedWorldElementIds: string[] = [];
|
||||
const changedIncidentIds: string[] = [];
|
||||
const changedPlotPointIds: string[] = [];
|
||||
const changedIssueIds: string[] = [];
|
||||
const changedActSummaryIds: string[] = [];
|
||||
let guideLineChanged: boolean = false;
|
||||
let aiGuideLineChanged: boolean = false;
|
||||
|
||||
newerBook.chapters.forEach((newerChapter: SyncedChapter): void => {
|
||||
const olderChapter: SyncedChapter | undefined = olderBook.chapters.find((chapter: SyncedChapter): boolean => chapter.id === newerChapter.id);
|
||||
|
||||
if (!olderChapter) {
|
||||
changedChapterIds.push(newerChapter.id);
|
||||
newerChapter.contents.forEach((content: SyncedChapterContent): void => {
|
||||
changedChapterContentIds.push(content.id);
|
||||
});
|
||||
if (newerChapter.info) {
|
||||
changedChapterInfoIds.push(newerChapter.info.id);
|
||||
}
|
||||
} else if (newerChapter.lastUpdate > olderChapter.lastUpdate) {
|
||||
changedChapterIds.push(newerChapter.id);
|
||||
} else {
|
||||
newerChapter.contents.forEach((newerContent: SyncedChapterContent): void => {
|
||||
const olderContent: SyncedChapterContent | undefined = olderChapter.contents.find((content: SyncedChapterContent): boolean => content.id === newerContent.id);
|
||||
if (!olderContent || newerContent.lastUpdate > olderContent.lastUpdate) {
|
||||
changedChapterContentIds.push(newerContent.id);
|
||||
}
|
||||
});
|
||||
|
||||
if (newerChapter.info && olderChapter.info) {
|
||||
if (newerChapter.info.lastUpdate > olderChapter.info.lastUpdate) {
|
||||
changedChapterInfoIds.push(newerChapter.info.id);
|
||||
}
|
||||
} else if (newerChapter.info && !olderChapter.info) {
|
||||
changedChapterInfoIds.push(newerChapter.info.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
newerBook.characters.forEach((newerCharacter: SyncedCharacter): void => {
|
||||
const olderCharacter: SyncedCharacter | undefined = olderBook.characters.find((character: SyncedCharacter): boolean => character.id === newerCharacter.id);
|
||||
|
||||
if (!olderCharacter) {
|
||||
changedCharacterIds.push(newerCharacter.id);
|
||||
newerCharacter.attributes.forEach((attribute: SyncedCharacterAttribute): void => {
|
||||
changedCharacterAttributeIds.push(attribute.id);
|
||||
});
|
||||
} else if (newerCharacter.lastUpdate > olderCharacter.lastUpdate) {
|
||||
changedCharacterIds.push(newerCharacter.id);
|
||||
} else {
|
||||
newerCharacter.attributes.forEach((newerAttribute: SyncedCharacterAttribute): void => {
|
||||
const olderAttribute: SyncedCharacterAttribute | undefined = olderCharacter.attributes.find((attribute: SyncedCharacterAttribute): boolean => attribute.id === newerAttribute.id);
|
||||
if (!olderAttribute || newerAttribute.lastUpdate > olderAttribute.lastUpdate) {
|
||||
changedCharacterAttributeIds.push(newerAttribute.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
newerBook.locations.forEach((newerLocation: SyncedLocation): void => {
|
||||
const olderLocation: SyncedLocation | undefined = olderBook.locations.find((location: SyncedLocation): boolean => location.id === newerLocation.id);
|
||||
|
||||
if (!olderLocation) {
|
||||
changedLocationIds.push(newerLocation.id);
|
||||
newerLocation.elements.forEach((element: SyncedLocationElement): void => {
|
||||
changedLocationElementIds.push(element.id);
|
||||
element.subElements.forEach((subElement: SyncedLocationSubElement): void => {
|
||||
changedLocationSubElementIds.push(subElement.id);
|
||||
});
|
||||
});
|
||||
} else if (newerLocation.lastUpdate > olderLocation.lastUpdate) {
|
||||
changedLocationIds.push(newerLocation.id);
|
||||
} else {
|
||||
newerLocation.elements.forEach((newerElement: SyncedLocationElement): void => {
|
||||
const olderElement: SyncedLocationElement | undefined = olderLocation.elements.find((element: SyncedLocationElement): boolean => element.id === newerElement.id);
|
||||
|
||||
if (!olderElement) {
|
||||
changedLocationElementIds.push(newerElement.id);
|
||||
newerElement.subElements.forEach((subElement: SyncedLocationSubElement): void => {
|
||||
changedLocationSubElementIds.push(subElement.id);
|
||||
});
|
||||
} else if (newerElement.lastUpdate > olderElement.lastUpdate) {
|
||||
changedLocationElementIds.push(newerElement.id);
|
||||
} else {
|
||||
newerElement.subElements.forEach((newerSubElement: SyncedLocationSubElement): void => {
|
||||
const olderSubElement: SyncedLocationSubElement | undefined = olderElement.subElements.find((subElement: SyncedLocationSubElement): boolean => subElement.id === newerSubElement.id);
|
||||
if (!olderSubElement || newerSubElement.lastUpdate > olderSubElement.lastUpdate) {
|
||||
changedLocationSubElementIds.push(newerSubElement.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
newerBook.worlds.forEach((newerWorld: SyncedWorld): void => {
|
||||
const olderWorld: SyncedWorld | undefined = olderBook.worlds.find((world: SyncedWorld): boolean => world.id === newerWorld.id);
|
||||
|
||||
if (!olderWorld) {
|
||||
changedWorldIds.push(newerWorld.id);
|
||||
newerWorld.elements.forEach((element: SyncedWorldElement): void => {
|
||||
changedWorldElementIds.push(element.id);
|
||||
});
|
||||
} else if (newerWorld.lastUpdate > olderWorld.lastUpdate) {
|
||||
changedWorldIds.push(newerWorld.id);
|
||||
} else {
|
||||
newerWorld.elements.forEach((newerElement: SyncedWorldElement): void => {
|
||||
const olderElement: SyncedWorldElement | undefined = olderWorld.elements.find((element: SyncedWorldElement): boolean => element.id === newerElement.id);
|
||||
if (!olderElement || newerElement.lastUpdate > olderElement.lastUpdate) {
|
||||
changedWorldElementIds.push(newerElement.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
newerBook.incidents.forEach((newerIncident: SyncedIncident): void => {
|
||||
const olderIncident: SyncedIncident | undefined = olderBook.incidents.find((incident: SyncedIncident): boolean => incident.id === newerIncident.id);
|
||||
if (!olderIncident || newerIncident.lastUpdate > olderIncident.lastUpdate) {
|
||||
changedIncidentIds.push(newerIncident.id);
|
||||
}
|
||||
});
|
||||
|
||||
newerBook.plotPoints.forEach((newerPlotPoint: SyncedPlotPoint): void => {
|
||||
const olderPlotPoint: SyncedPlotPoint | undefined = olderBook.plotPoints.find((plotPoint: SyncedPlotPoint): boolean => plotPoint.id === newerPlotPoint.id);
|
||||
if (!olderPlotPoint || newerPlotPoint.lastUpdate > olderPlotPoint.lastUpdate) {
|
||||
changedPlotPointIds.push(newerPlotPoint.id);
|
||||
}
|
||||
});
|
||||
|
||||
newerBook.issues.forEach((newerIssue: SyncedIssue): void => {
|
||||
const olderIssue: SyncedIssue | undefined = olderBook.issues.find((issue: SyncedIssue): boolean => issue.id === newerIssue.id);
|
||||
if (!olderIssue || newerIssue.lastUpdate > olderIssue.lastUpdate) {
|
||||
changedIssueIds.push(newerIssue.id);
|
||||
}
|
||||
});
|
||||
|
||||
newerBook.actSummaries.forEach((newerActSummary: SyncedActSummary): void => {
|
||||
const olderActSummary: SyncedActSummary | undefined = olderBook.actSummaries.find((actSummary: SyncedActSummary): boolean => actSummary.id === newerActSummary.id);
|
||||
if (!olderActSummary || newerActSummary.lastUpdate > olderActSummary.lastUpdate) {
|
||||
changedActSummaryIds.push(newerActSummary.id);
|
||||
}
|
||||
});
|
||||
|
||||
if (newerBook.guideLine && olderBook.guideLine) {
|
||||
guideLineChanged = newerBook.guideLine.lastUpdate > olderBook.guideLine.lastUpdate;
|
||||
} else if (newerBook.guideLine && !olderBook.guideLine) {
|
||||
guideLineChanged = true;
|
||||
}
|
||||
|
||||
if (newerBook.aiGuideLine && olderBook.aiGuideLine) {
|
||||
aiGuideLineChanged = newerBook.aiGuideLine.lastUpdate > olderBook.aiGuideLine.lastUpdate;
|
||||
} else if (newerBook.aiGuideLine && !olderBook.aiGuideLine) {
|
||||
aiGuideLineChanged = true;
|
||||
}
|
||||
|
||||
const hasChanges: boolean =
|
||||
changedChapterIds.length > 0 ||
|
||||
changedChapterContentIds.length > 0 ||
|
||||
changedChapterInfoIds.length > 0 ||
|
||||
changedCharacterIds.length > 0 ||
|
||||
changedCharacterAttributeIds.length > 0 ||
|
||||
changedLocationIds.length > 0 ||
|
||||
changedLocationElementIds.length > 0 ||
|
||||
changedLocationSubElementIds.length > 0 ||
|
||||
changedWorldIds.length > 0 ||
|
||||
changedWorldElementIds.length > 0 ||
|
||||
changedIncidentIds.length > 0 ||
|
||||
changedPlotPointIds.length > 0 ||
|
||||
changedIssueIds.length > 0 ||
|
||||
changedActSummaryIds.length > 0 ||
|
||||
guideLineChanged ||
|
||||
aiGuideLineChanged;
|
||||
|
||||
if (!hasChanges) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: newerBook.id,
|
||||
chapters: changedChapterIds,
|
||||
chapterContents: changedChapterContentIds,
|
||||
chapterInfos: changedChapterInfoIds,
|
||||
characters: changedCharacterIds,
|
||||
characterAttributes: changedCharacterAttributeIds,
|
||||
locations: changedLocationIds,
|
||||
locationElements: changedLocationElementIds,
|
||||
locationSubElements: changedLocationSubElementIds,
|
||||
worlds: changedWorldIds,
|
||||
worldElements: changedWorldElementIds,
|
||||
incidents: changedIncidentIds,
|
||||
plotPoints: changedPlotPointIds,
|
||||
issues: changedIssueIds,
|
||||
actSummaries: changedActSummaryIds,
|
||||
guideLine: guideLineChanged,
|
||||
aiGuideLine: aiGuideLineChanged
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user