Skip to content

Commit

Permalink
Refactor cache.ts: Update cache configuration and add cache utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
Adammatthiesen committed Dec 17, 2024
1 parent b4ccd17 commit 80f1c08
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 80 deletions.
122 changes: 42 additions & 80 deletions packages/studiocms_core/src/sdk-utils/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import type {
StudioCMSCacheObject,
} from './types';
import studioCMS_SDK_UPDATE from './update';
import { Expire, StudioCMS_SDK_Error } from './utils';
import {
Expire,
StudioCMS_SDK_Error,
cacheMapSet,
handleError,
transformNewDataReturn,
transformSiteConfigReturn,
} from './utils';

export type { STUDIOCMS_SDK_CACHE, PageDataCacheObject, SiteConfigCacheObject };

Expand Down Expand Up @@ -46,47 +53,38 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
page: {
byId: async (id) => {
try {
console.log('Getting page by ID', id);
if (!isEnabled) {
console.log('Cache is disabled');
const pageData = await studioCMS_SDK_GET.databaseEntry.pages.byId(id);

if (!pageData) {
throw new StudioCMS_SDK_Error('Could not retrieve data from the database.');
}
return {
id,
lastCacheUpdate: new Date(),
data: pageData,
};
return transformNewDataReturn(pageData);
}

const isCached = cache.pages.get(id);

if (!isCached) {
const updatedData = await studioCMS_SDK_GET.databaseEntry.pages.byId(id);
if (updatedData) {
cache.pages.set(id, { lastCacheUpdate: new Date(), data: updatedData });
return { id, lastCacheUpdate: new Date(), data: updatedData };
cacheMapSet(cache.pages, id, updatedData);
return transformNewDataReturn(updatedData);
}
throw new StudioCMS_SDK_Error('Cache entry does not exist.');
}

if (isEntryExpired(isCached)) {
const updatedData = await studioCMS_SDK_GET.databaseEntry.pages.byId(id);
if (updatedData) {
cache.pages.set(id, { lastCacheUpdate: new Date(), data: updatedData });
return { id, lastCacheUpdate: new Date(), data: updatedData };
cacheMapSet(cache.pages, id, updatedData);
return transformNewDataReturn(updatedData);
}
throw new StudioCMS_SDK_Error('Cache entry expired and could not be updated.');
}

return isCached;
} catch (error) {
if (error instanceof StudioCMS_SDK_Error) {
throw new StudioCMS_SDK_Error(error.message);
}
throw new StudioCMS_SDK_Error('Could not retrieve data from the database.');
throw handleError(error, 'Could not retrieve data from the database.');
}
},
bySlug: async (slug, pkg) => {
Expand All @@ -97,11 +95,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
if (!pageData) {
throw new StudioCMS_SDK_Error('Could not retrieve data from the database.');
}
return {
id: pageData.id,
lastCacheUpdate: new Date(),
data: pageData,
};
return transformNewDataReturn(pageData);
}
const cacheMap = cache.pages.values();
const cacheArray = Array.from(cacheMap);
Expand All @@ -112,27 +106,24 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
if (!isCached) {
const updatedData = await studioCMS_SDK_GET.databaseEntry.pages.bySlug(slug, pkg);
if (updatedData) {
cache.pages.set(updatedData.id, { lastCacheUpdate: new Date(), data: updatedData });
return { id: updatedData.id, lastCacheUpdate: new Date(), data: updatedData };
cacheMapSet(cache.pages, updatedData.id, updatedData);
return transformNewDataReturn(updatedData);
}
throw new StudioCMS_SDK_Error('Cache entry does not exist.');
}

if (isEntryExpired(isCached)) {
const updatedData = await studioCMS_SDK_GET.databaseEntry.pages.bySlug(slug, pkg);
if (updatedData) {
cache.pages.set(updatedData.id, { lastCacheUpdate: new Date(), data: updatedData });
return { id: updatedData.id, lastCacheUpdate: new Date(), data: updatedData };
cacheMapSet(cache.pages, updatedData.id, updatedData);
return transformNewDataReturn(updatedData);
}
throw new StudioCMS_SDK_Error('Cache entry expired and could not be updated.');
}

return isCached;
} catch (error) {
if (error instanceof StudioCMS_SDK_Error) {
throw new StudioCMS_SDK_Error(error.message);
}
throw new StudioCMS_SDK_Error('Could not retrieve data from the database.');
throw handleError(error, 'Could not retrieve data from the database.');
}
},
},
Expand All @@ -144,17 +135,17 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
if (!pages) {
throw new StudioCMS_SDK_Error('Could not retrieve data from the database.');
}
return pages.map((data) => ({ lastCacheUpdate: new Date(), data }));
return pages.map((data) => transformNewDataReturn(data));
}

// Check if cache is empty
if (cache.pages.size === 0) {
const updatedData = await studioCMS_SDK_GET.database.pages();
if (updatedData) {
for (const data of updatedData) {
cache.pages.set(data.id, { lastCacheUpdate: new Date(), data });
cacheMapSet(cache.pages, data.id, data);
}
return updatedData.map((data) => ({ lastCacheUpdate: new Date(), data }));
return updatedData.map((data) => transformNewDataReturn(data));
}
throw new StudioCMS_SDK_Error('Cache is empty and could not be updated.');
}
Expand All @@ -169,10 +160,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
cachedObject.data.id
);
if (updatedData) {
cache.pages.set(cachedObject.data.id, {
lastCacheUpdate: new Date(),
data: updatedData,
});
cacheMapSet(cache.pages, updatedData.id, updatedData);
}
}
}
Expand All @@ -181,10 +169,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
const recentCacheArray = Array.from(grabRecentCache);
return recentCacheArray;
} catch (error) {
if (error instanceof StudioCMS_SDK_Error) {
throw new StudioCMS_SDK_Error(error.message);
}
throw new StudioCMS_SDK_Error('Could not retrieve data from the database.');
throw handleError(error, 'Could not retrieve data from the database.');
}
},
siteConfig: async () => {
Expand All @@ -195,13 +180,13 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
if (!siteConfig) {
throw new StudioCMS_SDK_Error('Could not retrieve data from the database.');
}
return { lastCacheUpdate: new Date(), data: siteConfig };
return transformSiteConfigReturn(siteConfig);
}

if (!cache.siteConfig) {
const updatedData = await studioCMS_SDK_GET.database.config();
if (updatedData) {
cache.siteConfig = { lastCacheUpdate: new Date(), data: updatedData };
cache.siteConfig = transformSiteConfigReturn(updatedData);
return cache.siteConfig;
}
throw new StudioCMS_SDK_Error('Cache is empty and could not be updated.');
Expand All @@ -219,10 +204,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {

return cache.siteConfig;
} catch (error) {
if (error instanceof StudioCMS_SDK_Error) {
throw new StudioCMS_SDK_Error(error.message);
}
throw new StudioCMS_SDK_Error('Could not retrieve data from the database.');
throw handleError(error, 'Could not retrieve data from the database.');
}
},
},
Expand All @@ -235,10 +217,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
}
cache.pages.delete(id);
} catch (error) {
if (error instanceof Error) {
throw new StudioCMS_SDK_Error(`Error clearing cache: ${error.message}`, error.stack);
}
throw new StudioCMS_SDK_Error('Error clearing cache: An unknown error occurred.');
throw handleError(error, 'Error clearing cache: An unknown error occurred.');
}
},
bySlug: (slug, pkg) => {
Expand All @@ -256,10 +235,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
cache.pages.delete(i);
}
} catch (error) {
if (error instanceof Error) {
throw new StudioCMS_SDK_Error(`Error clearing cache: ${error.message}`, error.stack);
}
throw new StudioCMS_SDK_Error('Error clearing cache: An unknown error occurred.');
throw handleError(error, 'Error clearing cache: An unknown error occurred.');
}
},
},
Expand All @@ -270,10 +246,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
}
cache.pages.clear();
} catch (error) {
if (error instanceof Error) {
throw new StudioCMS_SDK_Error(`Error clearing cache: ${error.message}`, error.stack);
}
throw new StudioCMS_SDK_Error('Error clearing cache: An unknown error occurred.');
throw handleError(error, 'Error clearing cache: An unknown error occurred.');
}
},
},
Expand All @@ -291,7 +264,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
throw new StudioCMS_SDK_Error('Could not retrieve updated data from the database.');
}

return { id, lastCacheUpdate: new Date(), data: updatedData };
return transformNewDataReturn(updatedData);
}
const isCached = cache.pages.get(id);
if (!isCached) {
Expand All @@ -306,14 +279,11 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
throw new StudioCMS_SDK_Error('Could not retrieve updated data from the database.');
}

cache.pages.set(id, { lastCacheUpdate: new Date(), data: updatedData });
cacheMapSet(cache.pages, id, updatedData);

return { id, lastCacheUpdate: new Date(), data: updatedData };
return transformNewDataReturn(updatedData);
} catch (error) {
if (error instanceof StudioCMS_SDK_Error) {
throw new StudioCMS_SDK_Error(error.message);
}
throw new StudioCMS_SDK_Error('Could not update page data in the database.');
throw handleError(error, 'Could not update page data in the database.');
}
},
bySlug: async (slug, pkg, { pageData, pageContent }) => {
Expand All @@ -328,7 +298,7 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
throw new StudioCMS_SDK_Error('Could not retrieve updated data from the database.');
}

return { id: updatedData.id, lastCacheUpdate: new Date(), data: updatedData };
return transformNewDataReturn(updatedData);
}
const cacheMap = cache.pages.values();
const cacheArray = Array.from(cacheMap);
Expand Down Expand Up @@ -356,16 +326,11 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
throw new StudioCMS_SDK_Error('Could not retrieve updated data from the database.');
}

const dataToInsert = { lastCacheUpdate: new Date(), data: updatedData };

cache.pages.set(updatedData.id, dataToInsert);
cacheMapSet(cache.pages, updatedData.id, updatedData);

return { id: updatedData.id, lastCacheUpdate: new Date(), data: updatedData };
return transformNewDataReturn(updatedData);
} catch (error) {
if (error instanceof StudioCMS_SDK_Error) {
throw new StudioCMS_SDK_Error(error.message);
}
throw new StudioCMS_SDK_Error('Could not update page data in the database.');
throw handleError(error, 'Could not update page data in the database.');
}
},
},
Expand All @@ -378,17 +343,14 @@ export const studioCMS_SDK_Cache: STUDIOCMS_SDK_CACHE = {
}

if (!isEnabled) {
return { lastCacheUpdate: new Date(), data: newConfig };
return transformSiteConfigReturn(newConfig);
}

cache.siteConfig = { lastCacheUpdate: new Date(), data: newConfig };
cache.siteConfig = transformSiteConfigReturn(newConfig);

return cache.siteConfig;
} catch (error) {
if (error instanceof StudioCMS_SDK_Error) {
throw new StudioCMS_SDK_Error(error.message);
}
throw new StudioCMS_SDK_Error('Could not update site config in the database.');
throw handleError(error, 'Could not update site config in the database.');
}
},
},
Expand Down
67 changes: 67 additions & 0 deletions packages/studiocms_core/src/sdk-utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ import type {
CombinedPageData,
CombinedRank,
CombinedUserData,
PageDataCacheObject,
SingleRank,
SiteConfig,
SiteConfigCacheObject,
StudioCMSCacheObject,
tsPageDataSelect,
tsPermissionsSelect,
tsUsersSelect,
Expand Down Expand Up @@ -205,3 +209,66 @@ export function Expire(cacheConfig: CacheConfig) {
return new Date().getTime() - entry.lastCacheUpdate.getTime() > cacheConfig.lifetime;
};
}

/**
* Transforms the provided CombinedPageData into a PageDataCacheObject.
*
* @param data - The combined page data to be transformed.
* @returns An object containing the last cache update timestamp and the provided data.
*/
export function transformNewDataReturn(data: CombinedPageData): PageDataCacheObject {
return { lastCacheUpdate: new Date(), data };
}

/**
* Sets a new entry in the cache map with the provided key and transformed data.
*
* @param cache - The cache Map object where the data will be stored.
* @param key - The key under which the data will be stored in the cache.
* @param data - The data to be transformed and stored in the cache.
*/
export function cacheMapSet(
cache: StudioCMSCacheObject['pages'],
key: string,
data: CombinedPageData
): void {
cache.set(key, transformNewDataReturn(data));
}

/**
* Transforms the given site configuration data into a cache object.
*
* @param data - The site configuration data to be transformed.
* @returns An object containing the last cache update timestamp and the transformed site configuration data.
*/
export function transformSiteConfigReturn(data: SiteConfig): SiteConfigCacheObject {
return { lastCacheUpdate: new Date(), data };
}

/**
* Handles an error by throwing a `StudioCMS_SDK_Error`.
*
* @param error - The error to handle. If the error is an instance of `StudioCMS_SDK_Error`,
* it rethrows the error. Otherwise, it wraps the error in a new `StudioCMS_SDK_Error`
* with the provided message and optional hint.
* @param message - The message to use if the error is not an instance of `StudioCMS_SDK_Error`.
* @param hint - Optional. A hint to help the user fix the error.
*
* @throws {StudioCMS_SDK_Error} - Throws an error with the appropriate message and hint.
*/
export function handleError(error: unknown, message: string): never {
if (error instanceof StudioCMS_SDK_Error) {
// If it's already a StudioCMS_SDK_Error, rethrow it
throw error;
}

// Extract original error details if available
const originalMessage = error instanceof Error ? error.message : String(error);
const originalStack = error instanceof Error ? error.stack : undefined;

// Create and throw a new StudioCMS_SDK_Error
throw new StudioCMS_SDK_Error(
`${message}${originalMessage ? `: ${originalMessage}` : ''}`,
originalStack
);
}

0 comments on commit 80f1c08

Please sign in to comment.