1
Fork 0

Restructure the storage files.

This commit is contained in:
Bauke 2023-06-27 13:51:04 +02:00
parent d7ddbe4620
commit df09098f89
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
17 changed files with 100 additions and 96 deletions

View File

@ -1,6 +1,6 @@
import {offset, type Offset} from "caret-pos"; import {offset, type Offset} from "caret-pos";
import {Component} from "preact"; import {Component} from "preact";
import {type UserLabelsData} from "../../storage/common.js"; import {type UserLabelsData} from "../../storage/exports.js";
import {log, querySelectorAll} from "../../utilities/exports.js"; import {log, querySelectorAll} from "../../utilities/exports.js";
type Props = { type Props = {

View File

@ -1,4 +1,4 @@
import {type HideVotesData} from "../../storage/common.js"; import {type HideVotesData} from "../../storage/exports.js";
import {log, querySelectorAll} from "../../utilities/exports.js"; import {log, querySelectorAll} from "../../utilities/exports.js";
export function runHideVotesFeature(data: HideVotesData) { export function runHideVotesFeature(data: HideVotesData) {

View File

@ -4,7 +4,7 @@ import {
type UserLabelsData, type UserLabelsData,
createValueUserLabel, createValueUserLabel,
saveUserLabels, saveUserLabels,
} from "../../storage/common.js"; } from "../../storage/exports.js";
import { import {
createElementFromString, createElementFromString,
isColorBright, isColorBright,

View File

@ -1,5 +1,5 @@
import {log, querySelectorAll} from "../../utilities/exports.js"; import {log, querySelectorAll} from "../../utilities/exports.js";
import {type UsernameColorsData} from "../../storage/common.js"; import {type UsernameColorsData} from "../../storage/exports.js";
export function runUsernameColorsFeature( export function runUsernameColorsFeature(
data: UsernameColorsData, data: UsernameColorsData,

View File

@ -1,6 +1,6 @@
import {type JSX, render} from "preact"; import {type JSX, render} from "preact";
import {extractGroups, initializeGlobals, log} from "../utilities/exports.js"; import {extractGroups, initializeGlobals, log} from "../utilities/exports.js";
import {Feature, fromStorage, Data} from "../storage/common.js"; import {Feature, fromStorage, Data} from "../storage/exports.js";
import { import {
AutocompleteFeature, AutocompleteFeature,
BackToTopFeature, BackToTopFeature,

View File

@ -4,7 +4,7 @@ import {
fromStorage, fromStorage,
Feature, Feature,
type HideVotesData, type HideVotesData,
} from "../../storage/common.js"; } from "../../storage/exports.js";
import {Setting, type SettingProps} from "./index.js"; import {Setting, type SettingProps} from "./index.js";
type State = { type State = {

View File

@ -2,7 +2,7 @@ import {Component, type ComponentChildren, type JSX} from "preact";
// eslint-disable-next-line n/file-extension-in-import // eslint-disable-next-line n/file-extension-in-import
import {useContext} from "preact/hooks"; import {useContext} from "preact/hooks";
import {AppContext} from "../context.js"; import {AppContext} from "../context.js";
import {type Feature} from "../../storage/common.js"; import {type Feature} from "../../storage/exports.js";
export type SettingProps = { export type SettingProps = {
children: ComponentChildren; children: ComponentChildren;

View File

@ -6,7 +6,7 @@ import {
type UsernameColor, type UsernameColor,
Feature, Feature,
fromStorage, fromStorage,
} from "../../storage/common.js"; } from "../../storage/exports.js";
import {Setting, type SettingProps} from "./index.js"; import {Setting, type SettingProps} from "./index.js";
type State = { type State = {

View File

@ -1,5 +1,5 @@
import {createContext} from "preact"; import {createContext} from "preact";
import {type Feature} from "../storage/common.js"; import {type Feature} from "../storage/exports.js";
type AppContextValues = { type AppContextValues = {
setActiveFeature: (feature: Feature) => void; setActiveFeature: (feature: Feature) => void;

View File

@ -1,4 +1,4 @@
import {Feature} from "../storage/common.js"; import {Feature} from "../storage/exports.js";
import { import {
AboutSetting, AboutSetting,
AnonymizeUsernamesSetting, AnonymizeUsernamesSetting,

View File

@ -7,7 +7,7 @@ import {
createReportTemplate, createReportTemplate,
initializeGlobals, initializeGlobals,
} from "../utilities/exports.js"; } from "../utilities/exports.js";
import {type Feature, Data, fromStorage} from "../storage/common.js"; import {type Feature, Data, fromStorage} from "../storage/exports.js";
import {AppContext} from "./context.js"; import {AppContext} from "./context.js";
import {features} from "./features.js"; import {features} from "./features.js";

View File

@ -12,7 +12,7 @@ import {
Feature, Feature,
createValueUserLabel, createValueUserLabel,
saveUserLabels, saveUserLabels,
} from "../storage/common.js"; } from "../storage/exports.js";
import "../scss/index.scss"; import "../scss/index.scss";
import "../scss/user-label-editor.scss"; import "../scss/user-label-editor.scss";

19
source/storage/enums.ts Normal file
View File

@ -0,0 +1,19 @@
export enum Feature {
AnonymizeUsernames = "anonymize-usernames",
Autocomplete = "autocomplete",
BackToTop = "back-to-top",
Debug = "debug",
HideVotes = "hide-votes",
JumpToNewComment = "jump-to-new-comment",
MarkdownToolbar = "markdown-toolbar",
ThemedLogo = "themed-logo",
UserLabels = "user-labels",
UsernameColors = "username-colors",
}
export enum Data {
EnabledFeatures = "enabled-features",
KnownGroups = "known-groups",
LatestActiveFeatureTab = "latest-active-feature-tab",
Version = "data-version",
}

View File

@ -1,25 +1,10 @@
import {createValue, type Value} from "@holllo/webextension-storage"; import {createValue, type Value} from "@holllo/webextension-storage";
import browser from "webextension-polyfill"; import browser from "webextension-polyfill";
import {collectUserLabels} from "./user-label.js";
import {Data, Feature} from "./enums.js";
export enum Feature { export * from "./user-label.js";
AnonymizeUsernames = "anonymize-usernames", export * from "./enums.js";
Autocomplete = "autocomplete",
BackToTop = "back-to-top",
Debug = "debug",
HideVotes = "hide-votes",
JumpToNewComment = "jump-to-new-comment",
MarkdownToolbar = "markdown-toolbar",
ThemedLogo = "themed-logo",
UserLabels = "user-labels",
UsernameColors = "username-colors",
}
export enum Data {
EnabledFeatures = "enabled-features",
KnownGroups = "known-groups",
LatestActiveFeatureTab = "latest-active-feature-tab",
Version = "data-version",
}
export type HideVotesData = { export type HideVotesData = {
otherComments: boolean; otherComments: boolean;
@ -28,16 +13,6 @@ export type HideVotesData = {
ownTopics: boolean; ownTopics: boolean;
}; };
export type UserLabel = {
color: string;
id: number;
priority: number;
text: string;
username: string;
};
export type UserLabelsData = Array<Value<UserLabel>>;
export type UsernameColor = { export type UsernameColor = {
color: string; color: string;
id: number; id: number;
@ -46,56 +21,6 @@ export type UsernameColor = {
export type UsernameColorsData = UsernameColor[]; export type UsernameColorsData = UsernameColor[];
/**
* Create a {@link Value}-wrapped {@link UserLabel}.
*/
export async function createValueUserLabel(
userLabel: UserLabel,
): Promise<UserLabelsData[number]> {
return createValue<UserLabel>({
deserialize: (input) => JSON.parse(input) as UserLabel,
serialize: (input) => JSON.stringify(input),
key: `${Feature.UserLabels}-${userLabel.id}`,
value: userLabel,
storage: browser.storage.sync,
});
}
/**
* Get all user labels from storage and combine them into a single array.
*/
export async function collectUserLabels(): Promise<UserLabelsData> {
const storage = await browser.storage.sync.get();
const userLabels = [];
for (const [key, value] of Object.entries(storage)) {
if (!key.startsWith(Feature.UserLabels)) {
continue;
}
userLabels.push(
await createValueUserLabel(JSON.parse(value as string) as UserLabel),
);
}
return userLabels;
}
/**
* Save all user labels to storage under individual keys.
*
* They are stored under individual keys so that we don't run into storage quota
* limits. If it was stored under a single key we would only be able to fit
* around 80-100 labels before hitting the limit.
* @param userLabels The user labels array to save.
*/
export async function saveUserLabels(
userLabels: UserLabelsData,
): Promise<void> {
for (const label of userLabels) {
await label.save();
}
}
export const storageValues = { export const storageValues = {
[Data.EnabledFeatures]: createValue({ [Data.EnabledFeatures]: createValue({
deserialize: (input) => new Set(JSON.parse(input) as Feature[]), deserialize: (input) => new Set(JSON.parse(input) as Feature[]),
@ -137,7 +62,6 @@ export const storageValues = {
}, },
storage: browser.storage.sync, storage: browser.storage.sync,
}), }),
// eslint-disable-next-line unicorn/prefer-top-level-await
[Feature.UserLabels]: collectUserLabels(), [Feature.UserLabels]: collectUserLabels(),
[Feature.UsernameColors]: createValue({ [Feature.UsernameColors]: createValue({
deserialize: (input) => JSON.parse(input) as UsernameColorsData, deserialize: (input) => JSON.parse(input) as UsernameColorsData,

View File

@ -1,6 +1,6 @@
import browser from "webextension-polyfill"; import browser from "webextension-polyfill";
import {setup} from "@holllo/test"; import {setup} from "@holllo/test";
import {Data, Feature} from "../common.js"; import {Data, Feature} from "../exports.js";
import {migrations} from "./migrations.js"; import {migrations} from "./migrations.js";
import {v112Sample} from "./v1-1-2.js"; import {v112Sample} from "./v1-1-2.js";

View File

@ -1,13 +1,11 @@
import {setup} from "@holllo/test";
import {type Migration} from "@holllo/migration-helper"; import {type Migration} from "@holllo/migration-helper";
import browser from "webextension-polyfill";
import { import {
Data, Data,
Feature, Feature,
createValueUserLabel, createValueUserLabel,
fromStorage, fromStorage,
saveUserLabels, saveUserLabels,
} from "../common.js"; } from "../exports.js";
import {v112DeserializeData, v112Sample, type V112Settings} from "./v1-1-2.js"; import {v112DeserializeData, v112Sample, type V112Settings} from "./v1-1-2.js";
export const migrations: Array<Migration<string>> = [ export const migrations: Array<Migration<string>> = [

View File

@ -0,0 +1,63 @@
import {createValue, type Value} from "@holllo/webextension-storage";
import browser from "webextension-polyfill";
import {Feature} from "./enums.js";
export type UserLabel = {
color: string;
id: number;
priority: number;
text: string;
username: string;
};
export type UserLabelsData = Array<Value<UserLabel>>;
/**
* Create a {@link Value}-wrapped {@link UserLabel}.
*/
export async function createValueUserLabel(
userLabel: UserLabel,
): Promise<UserLabelsData[number]> {
return createValue<UserLabel>({
deserialize: (input) => JSON.parse(input) as UserLabel,
serialize: (input) => JSON.stringify(input),
key: `${Feature.UserLabels}-${userLabel.id}`,
value: userLabel,
storage: browser.storage.sync,
});
}
/**
* Get all user labels from storage and combine them into a single array.
*/
export async function collectUserLabels(): Promise<UserLabelsData> {
const storage = await browser.storage.sync.get();
const userLabels = [];
for (const [key, value] of Object.entries(storage)) {
if (!key.startsWith(Feature.UserLabels)) {
continue;
}
userLabels.push(
await createValueUserLabel(JSON.parse(value as string) as UserLabel),
);
}
return userLabels;
}
/**
* Save all user labels to storage under individual keys.
*
* They are stored under individual keys so that we don't run into storage quota
* limits. If it was stored under a single key we would only be able to fit
* around 80-100 labels before hitting the limit.
* @param userLabels The user labels array to save.
*/
export async function saveUserLabels(
userLabels: UserLabelsData,
): Promise<void> {
for (const label of userLabels) {
await label.save();
}
}