mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-23 17:43:20 +00:00
fix: initialise missing compatibility markers without pausing
This commit is contained in:
1 parent
b83f837065
commit
126adcb955
22 files changed
+326
-212
No files matched your search
@@ -8,7 +8,7 @@ export const DATABASE_COMPATIBILITY_LEGACY_VERSION_KEY_PREFIX = "obsidian-live-s
|
||||
export const COMPATIBILITY_PAUSE_SETTING_MESSAGE =
|
||||
"Remote synchronisation is paused until this device's compatibility review has been completed.";
|
||||
|
||||
export type DatabaseCompatibilityVersionState = "missing" | "invalid" | "upgrade" | "downgrade";
|
||||
export type DatabaseCompatibilityVersionState = "invalid" | "upgrade" | "downgrade";
|
||||
|
||||
export interface DatabaseCompatibilityReason {
|
||||
source: "database-version";
|
||||
@@ -57,18 +57,9 @@ export interface CompatibilityEvaluationInput {
|
||||
|
||||
function databaseVersionReason(
|
||||
acknowledgedVersion: string | null,
|
||||
currentVersion: number,
|
||||
isNewVault: boolean
|
||||
currentVersion: number
|
||||
): DatabaseCompatibilityReason | undefined {
|
||||
if (acknowledgedVersion === null || acknowledgedVersion === "") {
|
||||
if (isNewVault) return undefined;
|
||||
return {
|
||||
source: "database-version",
|
||||
state: "missing",
|
||||
currentVersion,
|
||||
resumable: true,
|
||||
};
|
||||
}
|
||||
if (acknowledgedVersion === null || acknowledgedVersion === "") return undefined;
|
||||
|
||||
const parsed = Number(acknowledgedVersion);
|
||||
if (!Number.isSafeInteger(parsed)) {
|
||||
@@ -104,9 +95,8 @@ function databaseVersionReason(
|
||||
* The caller owns persistence, user interaction, and the actual replication gate.
|
||||
*/
|
||||
export function evaluateCompatibilityPause(input: CompatibilityEvaluationInput): CompatibilityEvaluation {
|
||||
const isNewVault = input.migrationState?.isNewVault === true;
|
||||
const reasons: CompatibilityPauseReason[] = [];
|
||||
const databaseReason = databaseVersionReason(input.acknowledgedVersion, input.currentVersion, isNewVault);
|
||||
const databaseReason = databaseVersionReason(input.acknowledgedVersion, input.currentVersion);
|
||||
if (databaseReason) reasons.push(databaseReason);
|
||||
|
||||
if (input.migrationState?.requiresSyncReview === true) {
|
||||
@@ -130,8 +120,7 @@ export function evaluateCompatibilityPause(input: CompatibilityEvaluationInput):
|
||||
|
||||
if (reasons.length === 0) {
|
||||
return {
|
||||
initialiseAcknowledgedVersion:
|
||||
isNewVault && (input.acknowledgedVersion === null || input.acknowledgedVersion === ""),
|
||||
initialiseAcknowledgedVersion: input.acknowledgedVersion === null || input.acknowledgedVersion === "",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -68,8 +68,32 @@ describe("database compatibility evaluation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("requires review when an existing Vault has no valid acknowledged version", () => {
|
||||
for (const acknowledgedVersion of [null, "invalid"]) {
|
||||
it.each([null, ""])(
|
||||
"initialises a missing marker (%s) without pausing an existing Vault",
|
||||
(acknowledgedVersion) => {
|
||||
const result = evaluateCompatibilityPause({
|
||||
acknowledgedVersion,
|
||||
currentVersion: 12,
|
||||
migrationState: migrationState(),
|
||||
legacyReviewMessage: "",
|
||||
});
|
||||
|
||||
expect(result).toEqual({ initialiseAcknowledgedVersion: true });
|
||||
}
|
||||
);
|
||||
|
||||
it("initialises a missing marker when no settings migration state is available", () => {
|
||||
expect(
|
||||
evaluateCompatibilityPause({
|
||||
acknowledgedVersion: null,
|
||||
currentVersion: 12,
|
||||
legacyReviewMessage: "",
|
||||
})
|
||||
).toEqual({ initialiseAcknowledgedVersion: true });
|
||||
});
|
||||
|
||||
it("requires review when an existing Vault has an invalid acknowledged version", () => {
|
||||
for (const acknowledgedVersion of ["invalid", "NaN", "12.5"]) {
|
||||
const result = evaluateCompatibilityPause({
|
||||
acknowledgedVersion,
|
||||
currentVersion: 12,
|
||||
@@ -77,39 +101,44 @@ describe("database compatibility evaluation", () => {
|
||||
legacyReviewMessage: "",
|
||||
});
|
||||
expect(result.pause?.resumable).toBe(true);
|
||||
expect(result.pause?.reasons[0]).toMatchObject({ source: "database-version" });
|
||||
expect(result.pause?.reasons[0]).toMatchObject({ source: "database-version", state: "invalid" });
|
||||
expect(result.initialiseAcknowledgedVersion).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("does not permit a future settings schema to be acknowledged by an older implementation", () => {
|
||||
const result = evaluateCompatibilityPause({
|
||||
acknowledgedVersion: "12",
|
||||
currentVersion: 12,
|
||||
migrationState: migrationState({
|
||||
sourceVersion: 3,
|
||||
targetVersion: 2,
|
||||
isFromFutureSchema: true,
|
||||
requiresSyncReview: true,
|
||||
}),
|
||||
legacyReviewMessage: "",
|
||||
});
|
||||
|
||||
expect(result.pause).toEqual({
|
||||
resumable: false,
|
||||
reasons: [
|
||||
{
|
||||
source: "settings-schema",
|
||||
it.each(["12", null])(
|
||||
"does not permit a future settings schema with marker %s to be acknowledged",
|
||||
(acknowledgedVersion) => {
|
||||
const result = evaluateCompatibilityPause({
|
||||
acknowledgedVersion,
|
||||
currentVersion: 12,
|
||||
migrationState: migrationState({
|
||||
sourceVersion: 3,
|
||||
currentVersion: 2,
|
||||
targetVersion: 2,
|
||||
isFromFutureSchema: true,
|
||||
resumable: false,
|
||||
reviewReasons: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
requiresSyncReview: true,
|
||||
}),
|
||||
legacyReviewMessage: "",
|
||||
});
|
||||
|
||||
it("retains a settings migration review in the host compatibility reason", () => {
|
||||
expect(result.pause).toEqual({
|
||||
resumable: false,
|
||||
reasons: [
|
||||
{
|
||||
source: "settings-schema",
|
||||
sourceVersion: 3,
|
||||
currentVersion: 2,
|
||||
isFromFutureSchema: true,
|
||||
resumable: false,
|
||||
reviewReasons: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(result.initialiseAcknowledgedVersion).toBe(false);
|
||||
}
|
||||
);
|
||||
|
||||
it.each(["12", null])("retains a settings migration review with marker %s", (acknowledgedVersion) => {
|
||||
const reviewReasons = [
|
||||
{
|
||||
code: "legacy-update-review-pending",
|
||||
@@ -118,7 +147,7 @@ describe("database compatibility evaluation", () => {
|
||||
},
|
||||
];
|
||||
const result = evaluateCompatibilityPause({
|
||||
acknowledgedVersion: "12",
|
||||
acknowledgedVersion,
|
||||
currentVersion: 12,
|
||||
migrationState: migrationState({
|
||||
sourceVersion: 9,
|
||||
@@ -137,27 +166,32 @@ describe("database compatibility evaluation", () => {
|
||||
resumable: true,
|
||||
reviewReasons,
|
||||
});
|
||||
expect(result.initialiseAcknowledgedVersion).toBe(false);
|
||||
});
|
||||
|
||||
it("compatibility: retains an earlier unstructured review when no structured reason can be reconstructed", () => {
|
||||
const result = evaluateCompatibilityPause({
|
||||
acknowledgedVersion: "12",
|
||||
currentVersion: 12,
|
||||
migrationState: migrationState(),
|
||||
legacyReviewMessage: "Review an earlier compatibility change.",
|
||||
});
|
||||
it.each(["12", null])(
|
||||
"compatibility: retains an earlier unstructured review with marker %s",
|
||||
(acknowledgedVersion) => {
|
||||
const result = evaluateCompatibilityPause({
|
||||
acknowledgedVersion,
|
||||
currentVersion: 12,
|
||||
migrationState: migrationState(),
|
||||
legacyReviewMessage: "Review an earlier compatibility change.",
|
||||
});
|
||||
|
||||
expect(result.pause).toEqual({
|
||||
resumable: true,
|
||||
reasons: [
|
||||
{
|
||||
source: "legacy-review",
|
||||
message: "Review an earlier compatibility change.",
|
||||
resumable: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
expect(result.pause).toEqual({
|
||||
resumable: true,
|
||||
reasons: [
|
||||
{
|
||||
source: "legacy-review",
|
||||
message: "Review an earlier compatibility change.",
|
||||
resumable: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(result.initialiseAcknowledgedVersion).toBe(false);
|
||||
}
|
||||
);
|
||||
|
||||
it("compatibility: scopes the earlier review marker to the Vault", () => {
|
||||
expect(legacyDatabaseCompatibilityVersionKey("Example Vault")).toBe("obsidian-live-sync-verExample Vault");
|
||||
|
||||
Reference in new issue
Block a user