Add a system to create migrations for existing storage.
This commit is contained in:
parent
e4e52ae5f7
commit
f00b4161c3
|
@ -4,12 +4,14 @@ import {
|
||||||
getManifest,
|
getManifest,
|
||||||
getNextQItem,
|
getNextQItem,
|
||||||
getSettings,
|
getSettings,
|
||||||
|
migrate,
|
||||||
newQItemID,
|
newQItemID,
|
||||||
QItem,
|
QItem,
|
||||||
QMessage,
|
QMessage,
|
||||||
removeQItem,
|
removeQItem,
|
||||||
saveSettings,
|
saveSettings,
|
||||||
updateBadge
|
updateBadge,
|
||||||
|
versionAsNumber
|
||||||
} from '.';
|
} from '.';
|
||||||
|
|
||||||
let timeoutID: number | null = null;
|
let timeoutID: number | null = null;
|
||||||
|
@ -61,17 +63,28 @@ browser.runtime.onMessage.addListener(async (request: QMessage<unknown>) => {
|
||||||
browser.runtime.onInstalled.addListener(async () => {
|
browser.runtime.onInstalled.addListener(async () => {
|
||||||
const manifest = getManifest();
|
const manifest = getManifest();
|
||||||
const settings = await getSettings();
|
const settings = await getSettings();
|
||||||
|
const versionGotUpdated =
|
||||||
|
versionAsNumber(manifest.version) > versionAsNumber(settings.latestVersion);
|
||||||
|
|
||||||
|
if (versionGotUpdated) {
|
||||||
|
// Set the previous sync storage data in the local storage as a backup.
|
||||||
|
const previous = await browser.storage.sync.get();
|
||||||
|
await browser.storage.local.clear();
|
||||||
|
await browser.storage.local.set(previous);
|
||||||
|
|
||||||
|
// Then migrate the sync storage data and update it.
|
||||||
|
const next = migrate(settings.latestVersion, previous);
|
||||||
|
next.latestVersion = manifest.version;
|
||||||
|
next.versionGotUpdated = versionGotUpdated;
|
||||||
|
|
||||||
|
await browser.storage.sync.clear();
|
||||||
|
await browser.storage.sync.set(next);
|
||||||
|
}
|
||||||
|
|
||||||
// Open the options page when:
|
// Open the options page when:
|
||||||
// * The extension is first installed or is updated.
|
// * The extension is first installed or is updated.
|
||||||
// * In development, for convenience.
|
// * In development, for convenience.
|
||||||
if (
|
if (versionGotUpdated || manifest.nodeEnv === 'development') {
|
||||||
manifest.version !== settings.latestVersion ||
|
|
||||||
manifest.nodeEnv === 'development'
|
|
||||||
) {
|
|
||||||
settings.latestVersion = manifest.version;
|
|
||||||
settings.versionGotUpdated = true;
|
|
||||||
await saveSettings(settings);
|
|
||||||
await openOptionsPage();
|
await openOptionsPage();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -73,5 +73,14 @@ export async function updateBadge(settings?: Settings): Promise<void> {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a version string as a number by removing the periods.
|
||||||
|
* @param version
|
||||||
|
*/
|
||||||
|
export function versionAsNumber(version: string): number {
|
||||||
|
return Number(version.replace(/\./g, ''));
|
||||||
|
}
|
||||||
|
|
||||||
export * from './components';
|
export * from './components';
|
||||||
|
export * from './migrations';
|
||||||
export * from './settings';
|
export * from './settings';
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import {Migration, QItem} from '../..';
|
||||||
|
|
||||||
|
export const migration_2020_11_26: Migration = {
|
||||||
|
date: new Date('2020-11-26T14:32:00.000Z'),
|
||||||
|
version: '0.1.7',
|
||||||
|
upgrade
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This upgrades the sync settings to use 'qi<ID>'-named objects for QItems instead
|
||||||
|
* of them being in an array.
|
||||||
|
* Relevant commit: a668da05a179851b2a1117ef2d6aa9cef48d4964
|
||||||
|
*/
|
||||||
|
function upgrade(previous: Record<string, any>): Record<string, any> {
|
||||||
|
const items: QItem[] = previous.queue ?? [];
|
||||||
|
const next: Record<string, any> = previous;
|
||||||
|
delete next.queue;
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
next['qi' + item.id.toString()] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
import {log, versionAsNumber} from '../..';
|
||||||
|
import {migration_2020_11_26} from './2020-11-26';
|
||||||
|
|
||||||
|
export type Migration = {
|
||||||
|
date: Date;
|
||||||
|
version: string;
|
||||||
|
upgrade: (previous: Record<string, any>) => Record<string, any>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const migrations: Migration[] = [migration_2020_11_26];
|
||||||
|
|
||||||
|
export function migrate(
|
||||||
|
latestVersion: string,
|
||||||
|
previous: Record<string, any>
|
||||||
|
): Record<string, any> {
|
||||||
|
let next = previous;
|
||||||
|
|
||||||
|
for (const migration of migrations) {
|
||||||
|
// If the saved version is >= the version from the migration, we've already
|
||||||
|
// handled it previously, so skip it.
|
||||||
|
if (versionAsNumber(latestVersion) >= versionAsNumber(migration.version)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(`Running migration ${migration.date.toISOString()}`);
|
||||||
|
next = migration.upgrade(previous);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
Loading…
Reference in New Issue