import browser from "webextension-polyfill"; import {migrate, type Migration} from "@holllo/migration-helper"; import {createValue} from "@holllo/webextension-storage"; import type {ItemKeyPrefix} from "../item/item.js"; /** The Queue Item type for versions `<0.3.0`. */ export type QueueItemPre030 = { added: Date; id: number; text: string; url: string; }; /** The Queue Item type for versions `>=0.3.0 <1.0.0`. */ export type QueueItem030 = { sortIndex: number; } & QueueItemPre030; /** The Queue Item type for versions `>=1.0.0`. */ export type QueueItem100 = { dateAdded: Date; id: number; text: string | undefined; url: string; }; /** All migrations for Queue storage. */ export const dataMigrations: Array> = [ { version: "0.1.7", async migrate(data: Record) { const migrated: Record = { version: "0.1.7", }; const items = (data.queue as QueueItemPre030[]) ?? []; for (const item of items) { const key = `qi${item.id}`; migrated[key] = item; } return migrated; }, }, { version: "0.3.0", async migrate(data: Record) { const migrated: Record = { version: "0.3.0", }; for (const [key, value] of Object.entries(data)) { if (key.startsWith("qi")) { const item: QueueItem030 = { sortIndex: value.id, ...value, }; migrated[key] = item; } } return migrated; }, }, { version: "1.0.0", async migrate(data: Record) { const migrated: Record = { version: "1.0.0", }; for (const [key, value] of Object.entries(data)) { if (key.startsWith("qi")) { const item: QueueItem100 = { dateAdded: new Date(value.added), id: value.id, text: value.text === "" ? undefined : value.text, url: value.url, }; const prefix: ItemKeyPrefix = "item-"; migrated[`${prefix}${item.id}`] = item; } } return migrated; }, }, ]; /** Run the migrations and apply the result to storage. */ export async function runMigrations(): Promise { const manifest = browser.runtime.getManifest(); const version = await createValue({ deserialize: (input) => input, serialize: (input) => input, key: "version", storage: browser.storage.sync, value: manifest.version, }); // Only when the current data version is lower than the manifest version // should the migrations run. if (version.value >= manifest.version) { return; } const migrated = await migrate( await browser.storage.sync.get(), version.value, dataMigrations, ); await browser.storage.sync.clear(); await browser.storage.sync.set(migrated as Record); }