From 350fe17918de96efb5f92a44d92f884be09a23cc Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 2 Dec 2025 09:43:09 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(sw)=20keep=20incremental=20version?= =?UTF-8?q?ing=20for=20IndexedDB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IndexDB need a integer versioning when upgrading the database, it has to be incremental. Before the fix, version 4.0.0 would give 400, when 3.10.0 would give 3100. That would cause an error and the database would be destroyed then recreated. We improve the way we compute the version number to ensure it is always incremental, avoiding such issues. --- .../src/features/service-worker/DocsDB.ts | 19 +++++++--- .../service-worker/__tests__/DocsDB.test.tsx | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/frontend/apps/impress/src/features/service-worker/__tests__/DocsDB.test.tsx diff --git a/src/frontend/apps/impress/src/features/service-worker/DocsDB.ts b/src/frontend/apps/impress/src/features/service-worker/DocsDB.ts index eb401f37..099fc9dd 100644 --- a/src/frontend/apps/impress/src/features/service-worker/DocsDB.ts +++ b/src/frontend/apps/impress/src/features/service-worker/DocsDB.ts @@ -33,12 +33,21 @@ interface IDocsDB extends DBSchema { type TableName = 'doc-list' | 'doc-item' | 'doc-mutation'; /** - * IndexDB version must be a integer - * @returns + * IndexDB prefers incremental versioning when upgrading the database, + * otherwise it may throw an error, and we need to destroy the database + * and recreate it. + * To calculate the version number, we use the following formula, + * assuring incremental versioning: + * version = major * 1000000 + minor * 1000 + patch + * ex: + * - version 1.2.3 => 1002003 + * - version 0.10.15 => 10015 + * - version 2.0.0 => 2000000 + * @returns number */ -const getCurrentVersion = () => { - const [major, minor, patch] = pkg.version.split('.'); - return parseFloat(`${major}${minor}${patch}`); +export const getCurrentVersion = () => { + const [major, minor, patch] = pkg.version.split('.').map(Number); + return major * 1000000 + minor * 1000 + patch; }; /** diff --git a/src/frontend/apps/impress/src/features/service-worker/__tests__/DocsDB.test.tsx b/src/frontend/apps/impress/src/features/service-worker/__tests__/DocsDB.test.tsx new file mode 100644 index 00000000..d815efb1 --- /dev/null +++ b/src/frontend/apps/impress/src/features/service-worker/__tests__/DocsDB.test.tsx @@ -0,0 +1,36 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; + +vi.mock('@/../package.json', () => ({ + default: { version: '0.0.0' }, +})); + +describe('DocsDB', () => { + afterEach(() => { + vi.clearAllMocks(); + vi.resetModules(); + }); + + let previousExpected = 0; + + [ + { version: '0.0.1', expected: 1 }, + { version: '0.10.15', expected: 10015 }, + { version: '1.0.0', expected: 1000000 }, + { version: '2.105.3', expected: 2105003 }, + { version: '3.0.0', expected: 3000000 }, + { version: '10.20.30', expected: 10020030 }, + ].forEach(({ version, expected }) => { + it(`correctly computes version for ${version}`, () => { + vi.doMock('@/../package.json', () => ({ + default: { version }, + })); + + return vi.importActual('../DocsDB').then((module: any) => { + const result = module.getCurrentVersion(); + expect(result).toBe(expected); + expect(result).toBeGreaterThan(previousExpected); + previousExpected = result; + }); + }); + }); +});