src/lib/storage/rules-storage.ts

Total Symbols
4
Lines of Code
74
Avg Complexity
1.5
Avg Coverage
100.0%

File Relationships

graph LR getRulesForUrl["getRulesForUrl"] getRules["getRules"] getRulesForUrl -->|calls| getRules click getRulesForUrl "../symbols/2b935c6ef7eab8ce.html" click getRules "../symbols/69aeb172cce4aa1c.html"

Symbols by Kind

function 4

All Symbols

Name Kind Visibility Status Lines Signature
getRules function exported- 14-16 getRules(): : Promise<FieldRule[]>
saveRule function exported- 23-40 saveRule(rule: FieldRule): : Promise<void>
deleteRule function exported- 46-52 deleteRule(ruleId: string): : Promise<void>
getRulesForUrl function exported- 59-64 getRulesForUrl(url: string): : Promise<FieldRule[]>

Full Source

/**
 * Rules storage — CRUD operations for field rules.
 */

import type { FieldRule } from "@/types";
import type {
  MutableStorageRepository,
  UrlFilterableRepository,
} from "@/types/interfaces";
import { STORAGE_KEYS, getFromStorage, updateStorageAtomically } from "./core";
import { matchUrlPattern } from "@/lib/url/match-url-pattern";

/** Retrieves all stored field rules. */
export async function getRules(): Promise<FieldRule[]> {
  return getFromStorage<FieldRule[]>(STORAGE_KEYS.RULES, []);
}

/**
 * Saves a field rule (upsert). Updates `updatedAt` on existing rules;
 * sets both `createdAt` and `updatedAt` on new ones.
 * @param rule - The rule to save
 */
export async function saveRule(rule: FieldRule): Promise<void> {
  await updateStorageAtomically(
    STORAGE_KEYS.RULES,
    [] as FieldRule[],
    (rules) => {
      const next = [...rules];
      const existingIndex = next.findIndex((r) => r.id === rule.id);

      if (existingIndex >= 0) {
        next[existingIndex] = { ...rule, updatedAt: Date.now() };
      } else {
        next.push({ ...rule, createdAt: Date.now(), updatedAt: Date.now() });
      }

      return next;
    },
  );
}

/**
 * Deletes a field rule by ID.
 * @param ruleId - The unique rule identifier
 */
export async function deleteRule(ruleId: string): Promise<void> {
  await updateStorageAtomically(
    STORAGE_KEYS.RULES,
    [] as FieldRule[],
    (rules) => rules.filter((r) => r.id !== ruleId),
  );
}

/**
 * Retrieves all rules whose `urlPattern` matches the given URL,
 * sorted by priority (highest first).
 * @param url - The page URL to match against
 */
export async function getRulesForUrl(url: string): Promise<FieldRule[]> {
  const rules = await getRules();
  return rules
    .filter((rule) => matchUrlPattern(url, rule.urlPattern))
    .sort((a, b) => b.priority - a.priority);
}

/** Type-safe repository implementation for rules */
export const rulesRepository: MutableStorageRepository<FieldRule> &
  UrlFilterableRepository<FieldRule> = {
  getAll: getRules,
  save: saveRule,
  remove: deleteRule,
  getForUrl: getRulesForUrl,
};