PrivateconstructorPrivate Static#instanceProtected_Protected_Protected_Protected_Protected_Protected_Protected_Protected_Protected_Protected_Protected_Protected_Protected_Protected_StaticgetGets the singleton instance of RecipeDatabase
The singleton RecipeDatabase instance
StaticscaleScales a recipe's ingredient quantities to a different number of persons
Creates a new recipe object with ingredient quantities adjusted proportionally for the target number of persons. If the recipe doesn't have a valid person count or already matches the target, returns the recipe unchanged.
The recipe to scale
The target number of persons to scale for
New recipe object with scaled ingredient quantities
Closes the database connection and resets all internal state
Use this method in test teardown (afterEach) to properly cleanup database resources between tests.
Promise that resolves when cleanup is complete
Initializes the database by creating tables and loading data into local cache
This method must be called before using any other database operations. It creates the necessary tables if they don't exist and loads all data into memory for faster access.
Promise that resolves when initialization is complete
Checks if the database is empty
Determines whether the database contains any data by checking if all three main tables (recipes, ingredients, and tags) are empty. This is useful for preventing duplicate data insertion during app initialization.
True if all main tables are empty, false if any table contains data
Adds a new ingredient to the database
The ingredient object to add
Promise resolving to the added ingredient with database ID
Adds a new tag to the database
The tag object to add
Promise resolving to the added tag with database ID
Adds multiple ingredients to the database in a single batch operation
Performs a batch insert for improved performance when adding multiple ingredients. Uses a database transaction to ensure atomicity and efficiency.
Array of ingredient objects to add
await db.addMultipleIngredients([
{
name: "Flour",
unit: "cups",
type: ingredientType.grain,
season: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
},
{
name: "Sugar",
unit: "cups",
type: ingredientType.sweetener,
season: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
}
]);
Adds multiple tags to the database in a single batch operation
Performs a batch insert for improved performance when adding multiple tags. Uses a database transaction to ensure atomicity and efficiency.
Array of tag objects to add
Adds a new recipe to the database
This method verifies that all ingredients and tags exist in the database, adding them automatically if they don't exist.
The recipe object to add
Promise that resolves when the recipe is added
Gets random ingredients of a specific type
The ingredient type to filter by
Number of random ingredients to return
Array of random ingredients of the specified type
Gets random tags from the database
Number of random tags to return
Array of random tags
Checks if a recipe exists in the database
Recipe to search for
True if recipe exists, false otherwise
Checks if a recipe is already in the menu
The recipe ID to check
True if recipe is in menu, false otherwise
Adds a recipe to the menu and regenerates the shopping list
If the recipe is already in the menu, increments its count. Otherwise, it adds the recipe to the menu table with count = 1.
The recipe to add to the menu
Toggles the cooked status of a menu item
The menu item ID to toggle
True if successful, false otherwise
Decrements the count of a menu item, removing it if count reaches 0
The menu item ID to decrement/remove
True if successful, false otherwise
Clears the entire menu
Returns the map of purchased ingredient states Key is ingredient name, value is whether it's purchased
Sets the purchase state for an ingredient
The ingredient name
Whether the ingredient is purchased
Clears all purchased ingredient states Called when the menu is cleared to start fresh
Scales and updates a single recipe in the database
Takes a pre-scaled recipe object and updates it in the database. This method is used for individual recipe updates during progressive scaling operations.
The recipe object that has already been scaled to target persons
Finds recipes with similar ingredients and quantities
Uses ingredient comparison and fuzzy text matching to find recipes that share similar ingredients and cooking methods.
The recipe to find similarities for
Array of similar recipes
Finds tags with similar names using fuzzy matching
The tag name to search for
Array of similar tags, sorted by relevance
Finds ingredients with similar names using fuzzy matching
Cleans ingredient names by removing parenthetical content and uses fuzzy search to find similar ingredients.
The ingredient name to search for
Array of similar ingredients, sorted by relevance
Finds similar ingredients for multiple names in a single operation
More efficient than calling findSimilarIngredients multiple times as it processes all names in one pass.
Array of ingredient names to search for
Map of original names to arrays of similar ingredients
Finds similar tags for multiple names in a single operation
More efficient than calling findSimilarTags multiple times as it processes all names in one pass.
Array of tag names to search for
Map of original names to arrays of similar tags
Gets all imported recipe source URLs for a specific provider
Returns URLs of recipes that have been successfully imported from the given provider. These recipes should be hidden from future discovery.
The provider identifier (e.g., 'hellofresh')
Set of source URLs for imported recipes
Gets all seen-but-not-imported recipe URLs for a specific provider
Returns URLs of recipes that were discovered but not imported. These recipes should be shown with a visual indicator.
The provider identifier (e.g., 'hellofresh')
Set of URLs for seen-but-not-imported recipes
Marks recipe URLs as seen for a specific provider
Records that the user has seen these recipes during discovery. Only adds new entries for URLs not already tracked.
The provider identifier (e.g., 'hellofresh')
Array of recipe URLs to mark as seen
Removes recipe URLs from seen history for a specific provider
Called after successful import to remove URLs from the "seen" list since they are now tracked as imported recipes.
The provider identifier (e.g., 'hellofresh')
Array of recipe URLs to remove from seen history
PrivategetLoads all purchased ingredients from the database
Map of ingredient name to purchased state
PrivateencodePrivateresetPrivateResets all internal state to empty values
PrivateconstructPrivateConstructs a Map structure for updating recipe data in the database
Converts an encoded recipe element into a Map structure suitable for database update operations, mapping column names to their corresponding values.
The encoded recipe data to construct update structure from
Map with column names as keys and recipe data as values
PrivateconstructPrivateConstructs a Map structure for updating ingredient data in the database
Converts an ingredient element into a Map structure suitable for database update operations, properly encoding seasonal data with separators.
The ingredient data to construct update structure from
Map with column names as keys and ingredient data as values
PrivateconstructPrivateConstructs a Map structure for updating tag data in the database
Converts a tag element into a Map structure suitable for database update operations.
The tag data to construct update structure from
Map with column names as keys and tag data as values
PrivateopenPrivatedeletePrivateverifyPrivateVerifies that all tags exist in the database and returns them with database IDs
Checks each tag against the local cache and returns the database versions. Throws an error listing all tags that are not found in the database.
Array of tags to verify
Array of tags with database IDs
PrivateverifyPrivateVerifies that all ingredients exist in the database and returns them with database IDs
Checks each ingredient against the local cache and returns the database versions with recipe-specific quantities and optional usage notes. Throws an error listing all ingredients that are not found.
Array of ingredients to verify
Array of ingredients with database IDs, recipe-specific quantities, and notes
PrivateconstructPrivateConstructs a Map structure for searching recipes in the database
Creates a search criteria Map using key recipe fields (title, description, image) for database query operations when searching without an ID.
The recipe data to construct search criteria from
Map with column names as keys and search values
PrivateconstructPrivateConstructs a Map structure for searching ingredients in the database
Creates a search criteria Map using key ingredient fields (name, unit, type) for database query operations when searching without an ID.
The ingredient data to construct search criteria from
Map with column names as keys and search values
PrivateconstructPrivateConstructs a Map structure for searching tags in the database
Creates a search criteria Map using the tag name for database query operations when searching without an ID.
The tag data to construct search criteria from
Map with column names as keys and search values
PrivateencodePrivateEncodes a recipe object for database storage
Converts a recipe from the application format to the database storage format, encoding all nested objects (tags, ingredients, preparation steps, nutrition) into string representations using appropriate separators.
The recipe object to encode for database storage
Encoded recipe element ready for database insertion/update
PrivatepreparePrivatePrepares recipe image URI for database storage
Handles temporary image URIs by saving them to permanent storage. If the image URI is already in permanent storage, returns it unchanged. This encapsulates all image preparation logic within the database layer.
The image URI from the recipe (temporary or permanent)
The recipe title used for filename generation
Promise resolving to the permanent image URI
PrivatedecodePrivateDecodes a recipe from database storage format to application format
Converts an encoded recipe element from the database into the full application format, decoding all nested data structures (ingredients, tags, preparation, nutrition) and resolving file paths and database references.
The encoded recipe data from database
Promise resolving to fully decoded recipe object
PrivatedecodePrivateDecodes an array of recipes from database storage format
Processes multiple encoded recipe elements from database queries, decoding each one into the full application format.
Array of encoded recipe elements from database
Promise resolving to array of fully decoded recipe objects
PrivateencodePrivateEncodes an ingredient for storage within a recipe's ingredients list
Converts an ingredient to a string representation containing the ingredient's database ID, quantity, and optional usage note. Used when storing ingredient references within recipe data.
Format: "ID--quantity" or "ID--quantity%%note" if note is present. This allows the same ingredient to appear multiple times with different usage contexts (e.g., "olive oil" for sauce vs garnish).
The ingredient object to encode
Encoded string, or empty string if ingredient not found in database
PrivatedecodePrivateDecodes ingredients from a recipe's encoded ingredient string
Parses the encoded ingredient string from a recipe, looking up each ingredient by ID in the database and combining it with the recipe-specific quantities and optional usage notes. Also calculates the combined seasonal availability.
Supports both old format (without notes) and new format (with notes):
Encoded string containing ingredient IDs, quantities, and optional notes
Promise resolving to tuple of [decoded ingredients array, combined season array]
// Old format (backward compatible)
Input: "1--250__2--100"
Output: [[ingredient1 with quantity 250, ingredient2 with quantity 100], ["5","6","7"]]
// New format with notes
Input: "1--200%%For sauce__1--100%%For garnish"
Output: [[ingredient1 with quantity 200 and note "For sauce", ingredient1 with quantity 100 and note "For garnish"], ...]
PrivateencodePrivateEncodes a single ingredient for database storage
Converts an ingredient element from application format into the encoded format required for database insertion. Joins seasonal data into a string representation using the encoding separator.
The ingredient object in application format
Encoded ingredient ready for database storage
PrivateencodePrivateEncodes a single tag for database storage
Converts a tag element from application format into the encoded format required for database insertion.
The tag object in application format
Encoded tag ready for database storage
PrivatedecodePrivateDecodes a single ingredient from database storage format
Converts an encoded ingredient element from the database into the application format, parsing the seasonal data from its encoded string representation.
The encoded ingredient data from database
Decoded ingredient object in application format
PrivatedecodePrivateDecodes an array of ingredients from database storage format
Processes multiple encoded ingredient elements from database queries, converting each one to the application format. Returns empty array if input is null, undefined, or empty.
Array of encoded ingredient elements from database
Array of decoded ingredient objects in application format
PrivatedecodePrivateCalculates the intersection of two seasonal availability arrays
Combines seasonal data from multiple ingredients to determine when a recipe can be made using seasonal ingredients. Returns months that are common to both seasons.
Previously calculated season array (accumulated from other ingredients)
Season array from current ingredient
Array of month strings that are available in both seasons
PrivateencodePrivateEncodes a tag for storage within a recipe's tags list
Converts a tag to its database ID string representation for storage within recipe data. Looks up the tag in the local cache if ID is missing.
The tag object to encode
String representation of the tag's database ID, or error message if not found
PrivatedecodePrivateDecodes tags from a recipe's encoded tag string
Parses the encoded tag string from a recipe, looking up each tag by ID in the database to get the full tag information including names.
Encoded string containing tag IDs separated by encoding separators
Promise resolving to array of decoded tag objects
PrivatedecodePrivateDecodes a single tag from database storage format
Converts an encoded tag element from the database into the application format.
The encoded tag data from database
Decoded tag object in application format
PrivatedecodePrivateDecodes an array of tags from database storage format
Processes multiple encoded tag elements from database queries, converting each one to the application format. Returns empty array if input is null, undefined, or empty.
Array of encoded tag elements from database
Array of decoded tag objects in application format
PrivateencodePrivateEncodes nutrition information for database storage
Converts a nutrition object to a string representation by joining all nutritional values with text separators for compact storage within recipe data.
The nutrition object to encode
String representation of all nutrition values separated by text separators
PrivatedecodePrivateDecodes nutrition information from database storage format
Parses an encoded nutrition string back into a nutrition object. Returns undefined if the string is empty or has invalid format.
Encoded string containing nutrition values separated by text separators
Decoded nutrition object or undefined if invalid/empty
PrivatedecodePrivateDecodes preparation steps from database storage format
Parses an encoded preparation string back into an array of preparation step objects. Each step can have both a title and description, or just a description.
Encoded string containing preparation steps
Array of preparation step objects with title and description
PrivategetPrivateRetrieves all recipes from the database
Fetches all recipe records from the database and decodes them into the application format for use in the local cache.
Promise resolving to array of all recipes in application format
PrivategetPrivateRetrieves all tags from the database
Fetches all tag records from the database and decodes them into the application format for use in the local cache.
Promise resolving to array of all tags in application format
PrivategetPrivateRetrieves all ingredients from the database
Fetches all ingredient records from the database and decodes them into the application format for use in the local cache.
Promise resolving to array of all ingredients in application format
PrivategetPrivateRetrieves all menu items from the database
Fetches all menu records from the database and decodes them into the application format for use in the local cache.
Promise resolving to array of all menu items in application format
PrivateencodePrivateEncodes a menu item for database storage
Converts a menu element from application format into the encoded format required for database insertion.
The menu item in application format
Encoded menu item ready for database storage
PrivatedecodePrivateDecodes a menu item from database storage format
Converts an encoded menu element from the database into the application format.
The encoded menu data from database
Decoded menu item in application format
PrivatedecodePrivateDecodes an array of menu items from database storage format
Processes multiple encoded menu elements from database queries, converting each one to the application format. Returns empty array if input is null, undefined, or empty.
Array of encoded menu elements from database
Array of decoded menu items in application format
PrivatearePrivateCompares two ingredient lists for similarity
Determines if two ingredient lists are similar by comparing both ingredient names and quantities per person. Uses a 20% threshold for quantity differences. Used in the similar recipes feature to find recipes with comparable ingredients.
First ingredient list to compare
Second ingredient list to compare
True if ingredients lists are similar, false otherwise
PrivatemigratePrivateMigrates the database to add source tracking columns if they don't exist
This migration adds SOURCE_URL and SOURCE_PROVIDER columns to the recipes table to support bulk import tracking. Runs safely even if columns already exist.
PrivatemigratePrivateMigrates wildcard '*' season values to explicit month lists in the ingredients table.
Converts SEASON = '*' to '1__2__3__4__5__6__7__8__9__10__11__12'. Idempotent — safe to run on every startup.
TODO: Remove this migration once all users have updated past this version.
PrivategetPrivateRetrieves all import history records from the database
Promise resolving to array of all import history records
PrivatedecodePrivateDecodes an import history record from database format
PrivateencodePrivateEncodes an import history record for database storage
RecipeDatabase - Singleton class for managing recipe data storage and operations
This class provides a comprehensive interface for managing recipes, ingredients, tags, and shopping lists using SQLite database. It implements the singleton pattern to ensure a single database instance throughout the application lifecycle.
Key Features:
Example