• Parses search query into tokens for field-specific filtering.

    Supported syntax:

    • genre:action - Filter by genre
    • format:manga - Filter by format
    • year:2020-2023 - Filter by year range
    • tag:isekai - Filter by tag
    • Plain text - Fuzzy search on titles

    Parameters

    • query: string

      Search query string.

    Returns QuerySyntaxToken[]

    Array of parsed tokens.

    export function parseQuerySyntax(query: string): QuerySyntaxToken[] {
    const tokens: QuerySyntaxToken[] = [];
    const parts = query.match(/(?:[^\s"]+|"[^"]*")+/g) || [];

    for (const part of parts) {
    // Remove quotes if present
    const cleaned = part.replaceAll(/(?:^")|(?:"$)/g, "");

    // Check for field:value pattern
    const fieldPattern = /^(genre|format|year|tag):(.+)$/i;
    const fieldMatch = fieldPattern.exec(cleaned);
    if (fieldMatch) {
    const [, field, value] = fieldMatch;

    // Handle year range (e.g., 2020-2023)
    if (field.toLowerCase() === "year" && value.includes("-")) {
    const [min, max] = value.split("-").map((v) => v.trim());
    tokens.push({
    type: "field",
    field: "year",
    value: `${min}-${max}`,
    });
    } else {
    tokens.push({
    type: "field",
    field: field.toLowerCase(),
    value,
    });
    }
    } else {
    // Plain text for fuzzy search
    tokens.push({
    type: "text",
    value: cleaned,
    });
    }
    }

    return tokens;
    }