100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
|
|
import { browser } from "wxt/browser";
|
||
|
|
|
||
|
|
import { createDefaultPlatformStates, supportedPlatforms, type StoredPlatformState } from "./platforms";
|
||
|
|
|
||
|
|
export interface ExtensionStorageState {
|
||
|
|
installation_key: string;
|
||
|
|
plugin_installation_id: number | null;
|
||
|
|
installation_token: string | null;
|
||
|
|
api_base_url: string | null;
|
||
|
|
platforms: StoredPlatformState[];
|
||
|
|
last_updated_at: string | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const STORAGE_KEY = "geo.publisher.state";
|
||
|
|
|
||
|
|
function nextInstallationKey(): string {
|
||
|
|
if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
|
||
|
|
return crypto.randomUUID();
|
||
|
|
}
|
||
|
|
return `geo-extension-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
function mergePlatformStates(platforms?: StoredPlatformState[]): StoredPlatformState[] {
|
||
|
|
const defaults = createDefaultPlatformStates();
|
||
|
|
if (!platforms?.length) {
|
||
|
|
return defaults;
|
||
|
|
}
|
||
|
|
|
||
|
|
const incoming = new Map(platforms.map((platform) => [platform.platform_id, platform]));
|
||
|
|
return defaults.map((platform) => {
|
||
|
|
const stored = incoming.get(platform.platform_id);
|
||
|
|
return stored ? { ...platform, ...stored } : platform;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
async function writeState(nextState: ExtensionStorageState): Promise<void> {
|
||
|
|
await browser.storage.local.set({
|
||
|
|
[STORAGE_KEY]: nextState,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function getExtensionState(): Promise<ExtensionStorageState> {
|
||
|
|
const storageValue = await browser.storage.local.get(STORAGE_KEY);
|
||
|
|
const stored = storageValue[STORAGE_KEY] as Partial<ExtensionStorageState> | undefined;
|
||
|
|
|
||
|
|
const nextState: ExtensionStorageState = {
|
||
|
|
installation_key: stored?.installation_key || nextInstallationKey(),
|
||
|
|
plugin_installation_id: stored?.plugin_installation_id ?? null,
|
||
|
|
installation_token: stored?.installation_token ?? null,
|
||
|
|
api_base_url: stored?.api_base_url ?? null,
|
||
|
|
platforms: mergePlatformStates(stored?.platforms),
|
||
|
|
last_updated_at: stored?.last_updated_at ?? null,
|
||
|
|
};
|
||
|
|
|
||
|
|
const shouldPersist =
|
||
|
|
!stored?.installation_key ||
|
||
|
|
!stored?.platforms ||
|
||
|
|
stored.platforms.length !== supportedPlatforms.length;
|
||
|
|
|
||
|
|
if (shouldPersist) {
|
||
|
|
await writeState(nextState);
|
||
|
|
}
|
||
|
|
|
||
|
|
return nextState;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function patchExtensionState(
|
||
|
|
patch: Partial<Omit<ExtensionStorageState, "platforms">> & { platforms?: StoredPlatformState[] },
|
||
|
|
): Promise<ExtensionStorageState> {
|
||
|
|
const current = await getExtensionState();
|
||
|
|
const nextState: ExtensionStorageState = {
|
||
|
|
...current,
|
||
|
|
...patch,
|
||
|
|
platforms: patch.platforms ? mergePlatformStates(patch.platforms) : current.platforms,
|
||
|
|
last_updated_at: new Date().toISOString(),
|
||
|
|
};
|
||
|
|
await writeState(nextState);
|
||
|
|
return nextState;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function updatePlatformState(
|
||
|
|
platformId: string,
|
||
|
|
updater: Partial<StoredPlatformState>,
|
||
|
|
): Promise<ExtensionStorageState> {
|
||
|
|
const current = await getExtensionState();
|
||
|
|
const platforms = current.platforms.map((platform) =>
|
||
|
|
platform.platform_id === platformId
|
||
|
|
? {
|
||
|
|
...platform,
|
||
|
|
...updater,
|
||
|
|
}
|
||
|
|
: platform,
|
||
|
|
);
|
||
|
|
return patchExtensionState({ platforms });
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function resetPlatformStates(): Promise<ExtensionStorageState> {
|
||
|
|
return patchExtensionState({ platforms: createDefaultPlatformStates() });
|
||
|
|
}
|