Advertisement

← vibesdk

worker/services/cache/wrapper.ts

1.7 KB Download file
/**
 * Cache wrapper for controller methods without decorators
 */

import { CacheService } from './CacheService';
import type { RouteContext } from '../../api/types/route-context';
import type { BaseController } from '../../api/controllers/baseController';

interface CacheOptions {
	ttlSeconds: number;
	tags?: string[];
}

type ControllerMethod<T extends BaseController> = (
	this: T,
	request: Request,
	env: Env,
	ctx: ExecutionContext,
	context: RouteContext
) => Promise<Response>;

/**
 * Wraps a controller method with caching functionality
 * Works without experimental decorators - pure higher-order function
 */
export function withCache<T extends BaseController>(
	method: ControllerMethod<T>,
	options: CacheOptions
): ControllerMethod<T> {
	const cacheService = new CacheService();

	return async function (
		this: T,
		request: Request,
		env: Env,
		ctx: ExecutionContext,
		context: RouteContext
	): Promise<Response> {
		// Try to get user for cache key differentiation
		let userId = context?.user?.id;

		// For public endpoints, try to get optional user if not already available
		if (!userId && 'getOptionalUser' in this && typeof this.getOptionalUser === 'function') {
			try {
				const user = await this.getOptionalUser(request, env);
				userId = user?.id;
			} catch {
				// Ignore auth errors for public endpoints
			}
		}

		// Use request directly as cache key (Cloudflare Workers way)
		const cacheKeyOrRequest = request;

		// Use cache wrapper
		return cacheService.withCache(
			cacheKeyOrRequest,
			() => method.call(this, request, env, ctx, context),
			{ ttlSeconds: options.ttlSeconds, tags: options.tags }
		);
	};
}