diff --git a/source/item/item.test.ts b/source/item/item.test.ts index def43c2..6d17f73 100644 --- a/source/item/item.test.ts +++ b/source/item/item.test.ts @@ -1,8 +1,13 @@ import {type TestContext, setup} from "@holllo/test"; import {type Value} from "@holllo/webextension-storage"; -import browser from "webextension-polyfill"; -import {type Item, createItem, nextItem, nextItemId, storage} from "./item.js"; +import { + type Item, + createItem, + nextItem, + nextItemId, + storageForPrefix, +} from "./item.js"; const testText = "Test Item"; const testUrl = "https://example.org/"; @@ -30,10 +35,8 @@ await setup( "Item", async (group) => { group.beforeAll(async () => { - // If we're in production and testing, clear item storage. - if (!$dev && $test) { - await storage.clear(); - } + // TODO: Temporarily store existing storage and run the tests, and then + // restore it again. }); group.test("create & nextItem", async (test) => { @@ -67,11 +70,7 @@ await setup( await Promise.all(items.map(async (item) => item.remove())); // After all items have been removed test that `nextItem` returns nothing. - // This test will fail if an item is left from development, to clear - // storage automatically run in production and have test enabled. - // ie. `NODE_ENV=production TEST=true makers dev` - // TODO: Temporarily store existing storage and run the tests, and then - // restore it again. + // This test will fail if an item is left from development. storedNext = await nextItem(); test.equals(storedNext, undefined, "next item is undefined"); }); diff --git a/source/item/item.ts b/source/item/item.ts index 7e3090f..e04b185 100644 --- a/source/item/item.ts +++ b/source/item/item.ts @@ -29,10 +29,13 @@ export type SerializedItem = { }; /** The key prefix for {@link Item}s. */ -export const itemKeyPrefix = "item-"; +export type ItemKeyPrefix = "item-" | "history-"; -/** The default storage area to use for {@link Item}s. */ -export const storage = browser.storage.sync; +export function storageForPrefix( + prefix: ItemKeyPrefix, +): browser.Storage.StorageArea { + return prefix === "item-" ? browser.storage.sync : browser.storage.local; +} /** * Serialize and JSON-stringify an {@link Item}. @@ -83,18 +86,20 @@ export const deserializeItem: Value["deserialize"] = ( * * @param text The text of the {@link Item} to create. * @param url The URL of the {@link Item} to create. + * @param itemKeyPrefix The prefix for the {@link Item} key. * @returns The created {@link Value} with inner {@link Item}. */ export async function createItem( text: Item["text"], url: Item["url"], + itemKeyPrefix: ItemKeyPrefix = "item-", ): Promise> { const nextId = await nextItemId(); const item = await createValue({ deserialize: deserializeItem, serialize: serializeItem, - storage, + storage: storageForPrefix(itemKeyPrefix), key: `${itemKeyPrefix}${nextId}`, value: { dateAdded: new Date(), @@ -108,11 +113,14 @@ export async function createItem( } /** - * Get all keys from storage that start with the {@link itemKeyPrefix}. + * Get all keys from storage that start with the {@link ItemKeyPrefix}. * * @returns The keys as a string array. */ -export async function getItemKeys(): Promise { +export async function getItemKeys( + itemKeyPrefix: ItemKeyPrefix, +): Promise { + const storage = storageForPrefix(itemKeyPrefix); const stored = Object.keys(await storage.get()); const keys = stored.filter((key) => key.startsWith(itemKeyPrefix)); return keys; @@ -123,9 +131,11 @@ export async function getItemKeys(): Promise { * * @returns The next ID as a number. */ -export async function nextItemId(): Promise { +export async function nextItemId( + itemKeyPrefix: ItemKeyPrefix = "item-", +): Promise { // Get all the item keys and sort them so the highest ID is first. - const keys = await getItemKeys(); + const keys = await getItemKeys(itemKeyPrefix); keys.sort((a, b) => b.localeCompare(a)); // Get the first key or use 0 if no items exist yet. @@ -142,8 +152,10 @@ export async function nextItemId(): Promise { * queue is empty. */ export async function nextItem(): Promise | undefined> { + const itemKeyPrefix: ItemKeyPrefix = "item-"; + // Get all the item keys and sort them so the lowest ID is first. - const keys = await getItemKeys(); + const keys = await getItemKeys(itemKeyPrefix); keys.sort((a, b) => a.localeCompare(b)); // If no keys exist then exit early. @@ -166,7 +178,8 @@ export async function nextItem(): Promise | undefined> { * Set the WebExtension's badge text to show the current {@link Item} count. */ export async function setBadgeText(): Promise { - const keys = await getItemKeys(); + const itemKeyPrefix: ItemKeyPrefix = "item-"; + const keys = await getItemKeys(itemKeyPrefix); const count = keys.length; const action: browser.Action.Static = $browser === "firefox" ? browser.browserAction : browser.action;