@epic-web/workshop-utils 6.45.6 → 6.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -249,6 +249,8 @@ export declare const directoryEmptyCache: {
249
249
  };
250
250
  export declare const discordCache: C.Cache<unknown>;
251
251
  export declare const epicApiCache: C.Cache<unknown>;
252
+ export declare function makeGlobalFsCache<CacheEntryType>(name: string): C.Cache<CacheEntryType>;
253
+ export declare const githubCache: C.Cache<unknown>;
252
254
  export declare const WorkshopCacheSchema: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
253
255
  key: z.ZodString;
254
256
  entry: z.ZodObject<{
@@ -389,6 +391,34 @@ export declare function getAllWorkshopCaches(): Promise<{
389
391
  }>;
390
392
  }>;
391
393
  }[]>;
394
+ export declare function globalCacheDirectoryExists(): Promise<boolean>;
395
+ export declare function getGlobalCaches(): Promise<{
396
+ workshopId: string;
397
+ caches: Array<{
398
+ name: string;
399
+ entries: Array<{
400
+ key: string;
401
+ entry: {
402
+ metadata: {
403
+ createdTime: number;
404
+ ttl?: number | null | undefined;
405
+ swr?: number | undefined;
406
+ };
407
+ value?: unknown;
408
+ };
409
+ size?: number | undefined;
410
+ filepath?: string | undefined;
411
+ } & {
412
+ filename: string;
413
+ }>;
414
+ skippedFiles?: Array<{
415
+ filename: string;
416
+ error: string;
417
+ size: number;
418
+ skipped: true;
419
+ }>;
420
+ }>;
421
+ }[]>;
392
422
  export declare function getWorkshopFileCaches(): Promise<Record<string, any>>;
393
423
  export declare function readEntryByPath(cacheFilePath: string): Promise<any>;
394
424
  export declare function deleteCache(): Promise<null | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"cache.server.d.ts","sourceRoot":"","sources":["../../src/cache.server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache.server.d.ts","sourceRoot":"","sources":["../../src/cache.server.ts"],"names":[],"mappings":"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"}
@@ -180,6 +180,50 @@ export const notificationsCache = makeSingletonCache('NotificationsCache');
180
180
  export const directoryEmptyCache = makeSingletonCache('DirectoryEmptyCache');
181
181
  export const discordCache = makeSingletonFsCache('DiscordCache');
182
182
  export const epicApiCache = makeSingletonFsCache('EpicApiCache');
183
+ export function makeGlobalFsCache(name) {
184
+ return remember(`global-${name}`, () => {
185
+ const cacheInstanceDir = path.join(cacheDir, 'global', name);
186
+ const fsCache = {
187
+ name: `Filesystem cache (global-${name})`,
188
+ async get(key) {
189
+ const filePath = path.join(cacheInstanceDir, md5(key));
190
+ try {
191
+ const stats = await fsExtra.stat(filePath);
192
+ if (stats.size > MAX_CACHE_FILE_SIZE) {
193
+ const sizeInMB = (stats.size / (1024 * 1024)).toFixed(2);
194
+ log.warn(`Skipping large cache file ${filePath} (${sizeInMB}MB > 3MB limit). ` +
195
+ `Consider clearing "${name}" cache for key: ${key}`);
196
+ return null;
197
+ }
198
+ }
199
+ catch (error) {
200
+ if (error instanceof Error &&
201
+ 'code' in error &&
202
+ error.code === 'ENOENT') {
203
+ return null;
204
+ }
205
+ }
206
+ const data = await readJSONWithRetries(filePath);
207
+ if (data?.entry)
208
+ return data.entry;
209
+ return null;
210
+ },
211
+ async set(key, entry) {
212
+ const filePath = path.join(cacheInstanceDir, md5(key));
213
+ const tempPath = `${filePath}.tmp`;
214
+ await fsExtra.ensureDir(path.dirname(filePath));
215
+ await fsExtra.writeJSON(tempPath, { key, entry });
216
+ await fsExtra.move(tempPath, filePath, { overwrite: true });
217
+ },
218
+ async delete(key) {
219
+ const filePath = path.join(cacheInstanceDir, md5(key));
220
+ await fsExtra.remove(filePath);
221
+ },
222
+ };
223
+ return fsCache;
224
+ });
225
+ }
226
+ export const githubCache = makeGlobalFsCache('GitHubCache');
183
227
  async function readJsonFilesInDirectory(dir) {
184
228
  const files = await fsExtra.readdir(dir);
185
229
  const entries = await Promise.all(files
@@ -343,13 +387,35 @@ export const WorkshopCacheSchema = z
343
387
  });
344
388
  export async function getAllWorkshopCaches() {
345
389
  const files = await readJsonFilesInDirectory(cacheDir);
346
- const parseResult = WorkshopCacheSchema.safeParse(files);
390
+ // Exclude the global directory from workshop caches
391
+ const { global, ...workshopCaches } = files;
392
+ const parseResult = WorkshopCacheSchema.safeParse(workshopCaches);
347
393
  if (!parseResult.success) {
348
394
  log.error('Failed to parse workshop caches:', parseResult.error);
349
395
  return [];
350
396
  }
351
397
  return parseResult.data;
352
398
  }
399
+ export async function globalCacheDirectoryExists() {
400
+ const globalCacheDir = path.join(cacheDir, 'global');
401
+ return await fsExtra.exists(globalCacheDir);
402
+ }
403
+ export async function getGlobalCaches() {
404
+ const globalCacheDir = path.join(cacheDir, 'global');
405
+ if (!(await fsExtra.exists(globalCacheDir))) {
406
+ return [];
407
+ }
408
+ const files = await readJsonFilesInDirectory(globalCacheDir);
409
+ const parseResult = WorkshopCacheSchema.safeParse({ global: files });
410
+ if (!parseResult.success) {
411
+ log.error('Failed to parse global caches:', parseResult.error);
412
+ return [];
413
+ }
414
+ return parseResult.data.map((workshopCache) => ({
415
+ ...workshopCache,
416
+ workshopId: 'global',
417
+ }));
418
+ }
353
419
  export async function getWorkshopFileCaches() {
354
420
  const workshopCacheDir = path.join(cacheDir, getEnv().EPICSHOP_WORKSHOP_INSTANCE_ID);
355
421
  const caches = readJsonFilesInDirectory(workshopCacheDir);
@@ -1 +1 @@
1
- {"version":3,"file":"cache.server.js","sourceRoot":"","sources":["../../src/cache.server.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { getEnv } from './init-env.js'\n\nimport path from 'path'\nimport * as C from '@epic-web/cachified'\nimport { type CacheEntry, type CreateReporter } from '@epic-web/cachified'\nimport { remember } from '@epic-web/remember'\nimport fsExtra from 'fs-extra'\nimport { LRUCache } from 'lru-cache'\nimport md5 from 'md5-hex'\nimport z from 'zod'\nimport {\n\ttype ExampleApp,\n\ttype PlaygroundApp,\n\ttype ProblemApp,\n\ttype SolutionApp,\n} from './apps.server.js'\nimport { resolveCacheDir } from './data-storage.server.js'\nimport { logger } from './logger.js'\nimport { type Notification } from './notifications.server.js'\nimport { cachifiedTimingReporter, type Timings } from './timing.server.js'\nimport { checkConnection } from './utils.server.js'\n\nconst MAX_CACHE_FILE_SIZE = 3 * 1024 * 1024 // 3MB in bytes\nconst cacheDir = resolveCacheDir()\nconst log = logger('epic:cache')\n\n// Throttle repeated Sentry reports for corrupted cache files to reduce noise\nconst corruptedReportThrottle = remember(\n\t'epic:cache:corruption-throttle',\n\t() => new LRUCache<string, number>({ max: 2000, ttl: 60_000 }),\n)\n\n// Format cache time helper function (copied from @epic-web/cachified for consistency)\nfunction formatCacheTime(\n\tmetadata: any,\n\tformatDuration: (ms: number) => string,\n): string {\n\tconst ttl = metadata?.ttl\n\tif (ttl === undefined || ttl === Infinity) return 'forever'\n\treturn formatDuration(ttl)\n}\n\n// Default duration formatter (copied from @epic-web/cachified for consistency)\nfunction defaultFormatDuration(ms: number): string {\n\tif (ms < 1000) return `${Math.round(ms)}ms`\n\tif (ms < 60000) return `${Math.round(ms / 1000)}s`\n\tif (ms < 3600000) return `${Math.round(ms / 60000)}m`\n\treturn `${Math.round(ms / 3600000)}h`\n}\n\n/**\n * Creates a cachified reporter that integrates with the Epic Workshop logger system.\n * Uses the pattern `epic:cache:{name-of-cache}` for logger namespaces.\n * Only logs when the specific cache namespace is enabled via NODE_DEBUG.\n */\nexport function epicCacheReporter<Value>({\n\tformatDuration = defaultFormatDuration,\n\tperformance = globalThis.performance || Date,\n}: {\n\tformatDuration?: (ms: number) => string\n\tperformance?: Pick<typeof Date, 'now'>\n} = {}): CreateReporter<Value> {\n\treturn ({ key, fallbackToCache, forceFresh, metadata, cache }) => {\n\t\t// Determine cache name for logger namespace\n\t\tconst cacheName =\n\t\t\tcache.name || cache.toString().replace(/^\\[object (.*?)]$/, '$1')\n\n\t\t// Create logger with epic:cache:{name} pattern\n\t\t// Extract a reasonable cache name from longer descriptions\n\t\tlet loggerSuffix = 'unknown'\n\t\tif (cacheName.includes('(') && cacheName.includes(')')) {\n\t\t\t// Extract name from \"Filesystem cache (CacheName)\" format\n\t\t\tconst match = cacheName.match(/\\(([^)]+)\\)/)\n\t\t\tloggerSuffix = (match?.[1] ?? 'unknown').toLowerCase()\n\t\t} else if (cacheName === 'LRUCache') {\n\t\t\t// For LRU caches, we can't determine the name from the cache object alone\n\t\t\tloggerSuffix = 'lru'\n\t\t} else {\n\t\t\tloggerSuffix = cacheName.toLowerCase()\n\t\t}\n\n\t\tconst cacheLog = log.logger(loggerSuffix)\n\n\t\tlet freshValue: unknown\n\t\tlet getFreshValueStartTs: number\n\t\tlet refreshValueStartTS: number\n\n\t\treturn (event) => {\n\t\t\tswitch (event.name) {\n\t\t\t\tcase 'getCachedValueStart': {\n\t\t\t\t\tcacheLog(`Starting cache lookup for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueEmpty': {\n\t\t\t\t\tcacheLog(`Cache miss for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueSuccess': {\n\t\t\t\t\tcacheLog(`Cache hit for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'done': {\n\t\t\t\t\tcacheLog(`Cache operation done for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueRead': {\n\t\t\t\t\tcacheLog(`Read cached value for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueHookPending': {\n\t\t\t\t\tcacheLog(`Waiting for ongoing fetch for fresh value for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueOutdated': {\n\t\t\t\t\tcacheLog(`Cached value for ${key} is outdated`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'checkCachedValueErrorObj': {\n\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t`check failed for cached value of ${key}\\nReason: ${event.reason}.\\nDeleting the cache key and trying to get a fresh value.`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'checkFreshValueErrorObj': {\n\t\t\t\t\tlog.error(\n\t\t\t\t\t\t`check failed for fresh value of ${key}\\nReason: ${event.reason}.`,\n\t\t\t\t\t\tfreshValue,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueCacheFallback': {\n\t\t\t\t\tcacheLog(\n\t\t\t\t\t\t`Falling back to cached value for ${key} due to error getting fresh value.`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'checkCachedValueError': {\n\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t`check failed for cached value of ${key}\\nReason: ${event.reason}.\\nDeleting the cache key and trying to get a fresh value.`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueError': {\n\t\t\t\t\tlog.error(\n\t\t\t\t\t\t`error with cache at ${key}. Deleting the cache key and trying to get a fresh value.`,\n\t\t\t\t\t\tevent.error,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueError': {\n\t\t\t\t\tlog.error(\n\t\t\t\t\t\t`getting a fresh value for ${key} failed`,\n\t\t\t\t\t\t{ fallbackToCache, forceFresh },\n\t\t\t\t\t\tevent.error,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueStart': {\n\t\t\t\t\tgetFreshValueStartTs = performance.now()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'writeFreshValueSuccess': {\n\t\t\t\t\tconst totalTime = performance.now() - getFreshValueStartTs\n\t\t\t\t\tif (event.written) {\n\t\t\t\t\t\tcacheLog(\n\t\t\t\t\t\t\t`Updated the cache value for ${key}.`,\n\t\t\t\t\t\t\t`Getting a fresh value for this took ${formatDuration(\n\t\t\t\t\t\t\t\ttotalTime,\n\t\t\t\t\t\t\t)}.`,\n\t\t\t\t\t\t\t`Caching for ${formatCacheTime(\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t\tformatDuration,\n\t\t\t\t\t\t\t)} in ${cacheName}.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcacheLog(\n\t\t\t\t\t\t\t`Not updating the cache value for ${key}.`,\n\t\t\t\t\t\t\t`Getting a fresh value for this took ${formatDuration(\n\t\t\t\t\t\t\t\ttotalTime,\n\t\t\t\t\t\t\t)}.`,\n\t\t\t\t\t\t\t`Thereby exceeding caching time of ${formatCacheTime(\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t\tformatDuration,\n\t\t\t\t\t\t\t)}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'writeFreshValueError': {\n\t\t\t\t\tlog.error(`error setting cache: ${key}`, event.error)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueSuccess': {\n\t\t\t\t\tfreshValue = event.value\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'checkFreshValueError': {\n\t\t\t\t\tlog.error(\n\t\t\t\t\t\t`check failed for fresh value of ${key}\\nReason: ${event.reason}.`,\n\t\t\t\t\t\tfreshValue,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'refreshValueStart': {\n\t\t\t\t\trefreshValueStartTS = performance.now()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'refreshValueSuccess': {\n\t\t\t\t\tcacheLog(\n\t\t\t\t\t\t`Background refresh for ${key} successful.`,\n\t\t\t\t\t\t`Getting a fresh value for this took ${formatDuration(\n\t\t\t\t\t\t\tperformance.now() - refreshValueStartTS,\n\t\t\t\t\t\t)}.`,\n\t\t\t\t\t\t`Caching for ${formatCacheTime(\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\tformatDuration,\n\t\t\t\t\t\t)} in ${cacheName}.`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'refreshValueError': {\n\t\t\t\t\tlog.error(`Background refresh for ${key} failed.`, event.error)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\t// @ts-expect-error Defensive programming: log unknown events for debugging\n\t\t\t\t\tcacheLog(`Unknown cache event \"${event.name}\" for key ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport const solutionAppCache =\n\tmakeSingletonFsCache<SolutionApp>('SolutionAppCache')\nexport const problemAppCache =\n\tmakeSingletonFsCache<ProblemApp>('ProblemAppCache')\nexport const exampleAppCache =\n\tmakeSingletonFsCache<ExampleApp>('ExampleAppCache')\nexport const playgroundAppCache =\n\tmakeSingletonFsCache<PlaygroundApp>('PlaygroundAppCache')\nexport const diffCodeCache = makeSingletonFsCache<string>('DiffCodeCache')\nexport const diffFilesCache = makeSingletonFsCache<string>('DiffFilesCache')\nexport const copyUnignoredFilesCache = makeSingletonCache<string>(\n\t'CopyUnignoredFilesCache',\n)\nexport const compiledMarkdownCache = makeSingletonFsCache<string>(\n\t'CompiledMarkdownCache',\n)\nexport const compiledCodeCache = makeSingletonCache<string>('CompiledCodeCache')\nexport const ogCache = makeSingletonCache<string>('OgCache')\nexport const compiledInstructionMarkdownCache = makeSingletonFsCache<{\n\tcode: string\n\ttitle: string | null\n\tepicVideoEmbeds: Array<string>\n}>('CompiledInstructionMarkdownCache')\nexport const dirModifiedTimeCache = makeSingletonCache<number>(\n\t'DirModifiedTimeCache',\n)\nexport const connectionCache = makeSingletonCache<boolean>('ConnectionCache')\nexport const checkForUpdatesCache = makeSingletonCache<{\n\tupdatesAvailable: boolean\n\tlocalCommit: string\n\tremoteCommit: string\n\tdiffLink: string | null\n}>('CheckForUpdatesCache')\nexport const notificationsCache =\n\tmakeSingletonCache<Array<Notification>>('NotificationsCache')\nexport const directoryEmptyCache = makeSingletonCache<boolean>(\n\t'DirectoryEmptyCache',\n)\n\nexport const discordCache = makeSingletonFsCache('DiscordCache')\nexport const epicApiCache = makeSingletonFsCache('EpicApiCache')\n\nasync function readJsonFilesInDirectory(\n\tdir: string,\n): Promise<Record<string, any>> {\n\tconst files = await fsExtra.readdir(dir)\n\tconst entries = await Promise.all(\n\t\tfiles\n\t\t\t.filter((file) => {\n\t\t\t\t// Filter out system files that should not be parsed as JSON\n\t\t\t\tconst lowercaseFile = file.toLowerCase()\n\t\t\t\treturn (\n\t\t\t\t\t!lowercaseFile.startsWith('.ds_store') &&\n\t\t\t\t\t!lowercaseFile.startsWith('.') &&\n\t\t\t\t\t!lowercaseFile.includes('thumbs.db')\n\t\t\t\t)\n\t\t\t})\n\t\t\t.map(async (file) => {\n\t\t\t\tconst filePath = path.join(dir, file)\n\t\t\t\tconst stats = await fsExtra.stat(filePath)\n\t\t\t\tif (stats.isDirectory()) {\n\t\t\t\t\tconst subEntries = await readJsonFilesInDirectory(filePath)\n\t\t\t\t\treturn [file, subEntries]\n\t\t\t\t} else {\n\t\t\t\t\t// Check file size before attempting to read JSON\n\t\t\t\t\tif (stats.size > MAX_CACHE_FILE_SIZE) {\n\t\t\t\t\t\tconst sizeInMB = (stats.size / (1024 * 1024)).toFixed(2)\n\t\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t\t`Skipping large cache file ${filePath} (${sizeInMB}MB > 3MB limit). ` +\n\t\t\t\t\t\t\t\t`Consider clearing cache or excluding this file type from the admin interface.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tfile,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\terror: `File too large (${sizeInMB}MB > 3MB limit)`,\n\t\t\t\t\t\t\t\tsize: stats.size,\n\t\t\t\t\t\t\t\tskipped: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\n\t\t\t\t\tconst data = await readJSONWithRetries(filePath)\n\t\t\t\t\tif (data) {\n\t\t\t\t\t\treturn [file, { ...data, size: stats.size, filepath: filePath }]\n\t\t\t\t\t}\n\n\t\t\t\t\treturn [file, null]\n\t\t\t\t}\n\t\t\t}),\n\t)\n\treturn Object.fromEntries(entries)\n}\n\n// Helper to read JSON with a couple retries; deletes corrupted files and warns\nasync function readJSONWithRetries(filePath: string): Promise<any | null> {\n\tconst maxRetries = 3\n\tconst baseDelay = 10\n\tfor (let attempt = 0; attempt <= maxRetries; attempt++) {\n\t\ttry {\n\t\t\treturn await fsExtra.readJSON(filePath)\n\t\t} catch (error: unknown) {\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\t'code' in error &&\n\t\t\t\t(error as NodeJS.ErrnoException).code === 'ENOENT'\n\t\t\t) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst isJsonParseError =\n\t\t\t\terror instanceof SyntaxError ||\n\t\t\t\t(error instanceof Error && error.message.includes('JSON'))\n\n\t\t\tif (isJsonParseError) {\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\tconst delay = baseDelay * Math.pow(2, attempt)\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`JSON parsing error on attempt ${attempt + 1}/${maxRetries + 1} for ${filePath}, retrying in ${delay}ms...`,\n\t\t\t\t\t)\n\t\t\t\t\tawait new Promise((r) => setTimeout(r, delay))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Final attempt failed: optionally report and delete file\n\t\t\t\tif (getEnv().SENTRY_DSN && getEnv().EPICSHOP_IS_PUBLISHED) {\n\t\t\t\t\tconst throttleKey = `readJSON:${md5(filePath)}`\n\t\t\t\t\tif (!corruptedReportThrottle.has(throttleKey)) {\n\t\t\t\t\t\tcorruptedReportThrottle.set(throttleKey, Date.now())\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst Sentry = await import('@sentry/react-router')\n\t\t\t\t\t\t\tSentry.withScope((scope) => {\n\t\t\t\t\t\t\t\tscope.setLevel('warning')\n\t\t\t\t\t\t\t\tscope.setTag('error_type', 'corrupted_cache_file')\n\t\t\t\t\t\t\t\tscope.setExtra('filePath', filePath)\n\t\t\t\t\t\t\t\tscope.setExtra('errorMessage', (error as Error).message)\n\t\t\t\t\t\t\t\tscope.setExtra('retryAttempts', attempt)\n\t\t\t\t\t\t\t\tSentry.captureException(error)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t} catch (sentryError) {\n\t\t\t\t\t\t\tconsole.error('Failed to log to Sentry:', sentryError)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Always delete corrupted files so subsequent reads can refetch\n\t\t\t\ttry {\n\t\t\t\t\tawait fsExtra.remove(filePath)\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`Deleted corrupted cache file after ${attempt + 1} attempts: ${filePath}`,\n\t\t\t\t\t)\n\t\t\t\t} catch (deleteError) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Failed to delete corrupted cache file ${filePath}:`,\n\t\t\t\t\t\tdeleteError,\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\t// Other errors: do not retry\n\t\t\tthrow error\n\t\t}\n\t}\n\n\treturn null\n}\n\nconst CacheEntrySchema = z.object({\n\tkey: z.string(),\n\tentry: z.object({\n\t\tvalue: z.unknown(),\n\t\tmetadata: z.object({\n\t\t\tcreatedTime: z.number(),\n\t\t\t// Stored JSON may serialize Infinity as null; allow number | null | undefined\n\t\t\tttl: z.number().nullable().optional(),\n\t\t\t// Some entries may omit swr; allow optional\n\t\t\tswr: z.number().optional(),\n\t\t}),\n\t}),\n\tsize: z.number().optional(), // File size in bytes\n\tfilepath: z.string().optional(), // Full filesystem path to the cache file\n})\n\n// Schema for files that were skipped due to size limits\nconst SkippedFileSchema = z.object({\n\terror: z.string(),\n\tsize: z.number(),\n\tskipped: z.literal(true),\n})\n\n// Combined schema that can handle both cache entries and skipped files\nconst CacheFileSchema = z.union([CacheEntrySchema, SkippedFileSchema])\n\ntype CacheEntryType = z.infer<typeof CacheEntrySchema>\n\nexport const WorkshopCacheSchema = z\n\t.record(z.record(z.record(CacheFileSchema)))\n\t.transform((workshopCaches) => {\n\t\ttype CacheEntryWithFilename = CacheEntryType & { filename: string }\n\t\ttype SkippedFileWithFilename = {\n\t\t\tfilename: string\n\t\t\terror: string\n\t\t\tsize: number\n\t\t\tskipped: true\n\t\t}\n\t\ttype Cache = {\n\t\t\tname: string\n\t\t\tentries: Array<CacheEntryWithFilename>\n\t\t\tskippedFiles?: Array<SkippedFileWithFilename>\n\t\t}\n\n\t\tconst cachesArray: Array<{\n\t\t\tworkshopId: string\n\t\t\tcaches: Array<Cache>\n\t\t}> = []\n\n\t\tfor (const [workshopId, caches] of Object.entries(workshopCaches)) {\n\t\t\tconst cachesInDir: Array<Cache> = []\n\t\t\tfor (const [cacheName, entriesObj] of Object.entries(caches)) {\n\t\t\t\tconst entries: Array<CacheEntryWithFilename> = []\n\t\t\t\tconst skippedFiles: Array<SkippedFileWithFilename> = []\n\n\t\t\t\tfor (const [key, value] of Object.entries(entriesObj)) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tvalue &&\n\t\t\t\t\t\ttypeof value === 'object' &&\n\t\t\t\t\t\t'skipped' in value &&\n\t\t\t\t\t\tvalue.skipped\n\t\t\t\t\t) {\n\t\t\t\t\t\t// This is a skipped file\n\t\t\t\t\t\tskippedFiles.push({\n\t\t\t\t\t\t\tfilename: key,\n\t\t\t\t\t\t\terror: value.error as string,\n\t\t\t\t\t\t\tsize: value.size as number,\n\t\t\t\t\t\t\tskipped: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is a regular cache entry\n\t\t\t\t\t\tentries.push({ ...(value as CacheEntryType), filename: key })\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst cache: Cache = { name: cacheName, entries }\n\t\t\t\tif (skippedFiles.length > 0) {\n\t\t\t\t\tcache.skippedFiles = skippedFiles\n\t\t\t\t}\n\t\t\t\tcachesInDir.push(cache)\n\t\t\t}\n\t\t\tcachesArray.push({ workshopId, caches: cachesInDir })\n\t\t}\n\n\t\treturn cachesArray\n\t})\n\nexport async function getAllWorkshopCaches() {\n\tconst files = await readJsonFilesInDirectory(cacheDir)\n\tconst parseResult = WorkshopCacheSchema.safeParse(files)\n\tif (!parseResult.success) {\n\t\tlog.error('Failed to parse workshop caches:', parseResult.error)\n\t\treturn []\n\t}\n\treturn parseResult.data\n}\n\nexport async function getWorkshopFileCaches() {\n\tconst workshopCacheDir = path.join(\n\t\tcacheDir,\n\t\tgetEnv().EPICSHOP_WORKSHOP_INSTANCE_ID,\n\t)\n\tconst caches = readJsonFilesInDirectory(workshopCacheDir)\n\treturn caches\n}\n\nexport async function readEntryByPath(cacheFilePath: string) {\n\tconst filePath = path.join(cacheDir, cacheFilePath)\n\tconst data = await readJSONWithRetries(filePath)\n\treturn data?.entry ?? null\n}\n\nexport async function deleteCache() {\n\tif (getEnv().EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (await fsExtra.exists(cacheDir)) {\n\t\t\tawait fsExtra.remove(cacheDir)\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(`Error deleting the cache in ${cacheDir}`, error)\n\t}\n}\n\nexport async function deleteCacheEntry(cacheFilePath: string) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tconst filePath = path.join(cacheDir, cacheFilePath)\n\t\tawait fsExtra.remove(filePath)\n\t} catch (error) {\n\t\tconsole.error(`Error deleting cache entry ${cacheFilePath}:`, error)\n\t}\n}\n\nexport async function deleteWorkshopCache(\n\tworkshopId: string,\n\tcacheName?: string,\n) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (cacheName) {\n\t\t\t// Delete specific cache within workshop\n\t\t\tconst cachePath = path.join(cacheDir, workshopId, cacheName)\n\t\t\tif (await fsExtra.exists(cachePath)) {\n\t\t\t\tawait fsExtra.remove(cachePath)\n\t\t\t}\n\t\t} else {\n\t\t\t// Delete entire workshop cache directory\n\t\t\tconst workshopCachePath = path.join(cacheDir, workshopId)\n\t\t\tif (await fsExtra.exists(workshopCachePath)) {\n\t\t\t\tawait fsExtra.remove(workshopCachePath)\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t`Error deleting workshop cache ${workshopId}/${cacheName || 'all'}:`,\n\t\t\terror,\n\t\t)\n\t}\n}\n\nexport async function updateCacheEntry(cacheFilePath: string, newEntry: any) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tconst filePath = path.join(cacheDir, cacheFilePath)\n\t\tconst existingData = await readJSONWithRetries(filePath)\n\t\tif (!existingData) {\n\t\t\tthrow new Error(`Cache file does not exist: ${cacheFilePath}`)\n\t\t}\n\n\t\tconst updatedData = {\n\t\t\t...existingData,\n\t\t\tentry: {\n\t\t\t\t...existingData.entry,\n\t\t\t\tvalue: newEntry,\n\t\t\t\tmetadata: {\n\t\t\t\t\t...existingData.entry.metadata,\n\t\t\t\t\tcreatedTime: Date.now(), // Update timestamp\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tawait fsExtra.writeJSON(filePath, updatedData)\n\t\treturn updatedData.entry\n\t} catch (error) {\n\t\tconsole.error(`Error updating cache entry ${cacheFilePath}:`, error)\n\t\tthrow error\n\t}\n}\n\nexport function makeSingletonCache<CacheEntryType>(name: string) {\n\treturn remember(name, () => {\n\t\tconst lruInstance = new LRUCache<string, CacheEntry<CacheEntryType>>({\n\t\t\tmax: 1000,\n\t\t})\n\n\t\tconst lru = {\n\t\t\tname,\n\t\t\tset: (key, value) => {\n\t\t\t\tconst ttl = C.totalTtl(value.metadata)\n\t\t\t\tlruInstance.set(key, value, {\n\t\t\t\t\tttl: ttl === Infinity ? undefined : ttl,\n\t\t\t\t\tstart: value.metadata.createdTime,\n\t\t\t\t})\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tget: (key) => lruInstance.get(key),\n\t\t\tdelete: (key) => lruInstance.delete(key),\n\t\t} satisfies C.Cache<CacheEntryType>\n\n\t\treturn lru\n\t})\n}\n\nexport function makeSingletonFsCache<CacheEntryType>(name: string) {\n\treturn remember(name, () => {\n\t\tconst cacheInstanceDir = path.join(\n\t\t\tcacheDir,\n\t\t\tgetEnv().EPICSHOP_WORKSHOP_INSTANCE_ID,\n\t\t\tname,\n\t\t)\n\n\t\tconst fsCache: C.Cache<CacheEntryType> = {\n\t\t\tname: `Filesystem cache (${name})`,\n\t\t\tasync get(key) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\n\t\t\t\t// Check file size before attempting to read\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = await fsExtra.stat(filePath)\n\t\t\t\t\tif (stats.size > MAX_CACHE_FILE_SIZE) {\n\t\t\t\t\t\tconst sizeInMB = (stats.size / (1024 * 1024)).toFixed(2)\n\t\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t\t`Skipping large cache file ${filePath} (${sizeInMB}MB > 3MB limit). ` +\n\t\t\t\t\t\t\t\t`Consider clearing \"${name}\" cache for key: ${key}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn null\n\t\t\t\t\t}\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\tif (\n\t\t\t\t\t\terror instanceof Error &&\n\t\t\t\t\t\t'code' in error &&\n\t\t\t\t\t\terror.code === 'ENOENT'\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn null\n\t\t\t\t\t}\n\t\t\t\t\t// For other stat errors, continue with the read attempt\n\t\t\t\t}\n\n\t\t\t\t// Use the shared helper which retries and deletes corrupted files\n\t\t\t\tconst data = await readJSONWithRetries(filePath)\n\t\t\t\tif (data?.entry) return data.entry\n\t\t\t\treturn null\n\n\t\t\t\t// This should never be reached, but just in case\n\t\t\t\treturn null\n\t\t\t},\n\t\t\tasync set(key, entry) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\t\t\t\tconst tempPath = `${filePath}.tmp`\n\t\t\t\tawait fsExtra.ensureDir(path.dirname(filePath))\n\t\t\t\t// Write to temp file first, then atomically move to final location\n\t\t\t\t// This prevents race conditions where readers see partially written JSON files\n\t\t\t\tawait fsExtra.writeJSON(tempPath, { key, entry })\n\t\t\t\tawait fsExtra.move(tempPath, filePath, { overwrite: true })\n\t\t\t},\n\t\t\tasync delete(key) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\t\t\t\tawait fsExtra.remove(filePath)\n\t\t\t},\n\t\t}\n\n\t\treturn fsCache\n\t})\n}\n\n/**\n * This wraps @epic-web/cachified to add a few handy features:\n *\n * 1. Automatic timing for timing headers\n * 2. Automatic force refresh based on the request and enhancement of forceFresh\n * to support comma-separated keys to force\n * 3. Offline fallback support. If a fallback is given and we are detected to be\n * offline, then the cached value is used regardless of whether it's expired and\n * if one is not present then the given fallback will be used.\n */\nexport async function cachified<Value>({\n\trequest,\n\ttimings,\n\tkey,\n\ttimingKey = key.length > 18 ? `${key.slice(0, 7)}...${key.slice(-8)}` : key,\n\tofflineFallbackValue,\n\t...options\n}: Omit<C.CachifiedOptions<Value>, 'forceFresh'> & {\n\trequest?: Request\n\ttimings?: Timings\n\tforceFresh?: boolean | string\n\ttimingKey?: string\n\tofflineFallbackValue?: Value\n}): Promise<Value> {\n\tif (offlineFallbackValue !== undefined) {\n\t\tconst isOnline = await checkConnection({ request, timings })\n\t\tif (!isOnline) {\n\t\t\tlog.warn(\n\t\t\t\t`Offline: using cached value for ${key} or offline fallback if no cache is present`,\n\t\t\t)\n\t\t\tconst cacheEntry = await options.cache.get(key)\n\t\t\treturn cacheEntry?.value ?? offlineFallbackValue\n\t\t}\n\t}\n\tconst forceFresh = await shouldForceFresh({\n\t\tforceFresh: options.forceFresh,\n\t\trequest,\n\t\tkey,\n\t})\n\treturn C.cachified(\n\t\t{\n\t\t\t...options,\n\t\t\tkey,\n\t\t\tforceFresh,\n\t\t},\n\t\tC.mergeReporters(\n\t\t\tcachifiedTimingReporter(timings, timingKey),\n\t\t\tepicCacheReporter(),\n\t\t),\n\t)\n}\n\nexport async function shouldForceFresh({\n\tforceFresh,\n\trequest,\n\tkey,\n}: {\n\tforceFresh?: boolean | string\n\trequest?: Request\n\tkey?: string\n}) {\n\tif (typeof forceFresh === 'boolean') return forceFresh\n\tif (typeof forceFresh === 'string' && key) {\n\t\treturn forceFresh.split(',').includes(key)\n\t}\n\n\tif (!request) return false\n\tconst fresh = new URL(request.url).searchParams.get('fresh')\n\tif (typeof fresh !== 'string') return false\n\tif (fresh === '') return true\n\tif (!key) return false\n\n\treturn fresh.split(',').includes(key)\n}\n"]}
1
+ {"version":3,"file":"cache.server.js","sourceRoot":"","sources":["../../src/cache.server.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { getEnv } from './init-env.js'\n\nimport path from 'path'\nimport * as C from '@epic-web/cachified'\nimport { type CacheEntry, type CreateReporter } from '@epic-web/cachified'\nimport { remember } from '@epic-web/remember'\nimport fsExtra from 'fs-extra'\nimport { LRUCache } from 'lru-cache'\nimport md5 from 'md5-hex'\nimport z from 'zod'\nimport {\n\ttype ExampleApp,\n\ttype PlaygroundApp,\n\ttype ProblemApp,\n\ttype SolutionApp,\n} from './apps.server.js'\nimport { resolveCacheDir } from './data-storage.server.js'\nimport { logger } from './logger.js'\nimport { type Notification } from './notifications.server.js'\nimport { cachifiedTimingReporter, type Timings } from './timing.server.js'\nimport { checkConnection } from './utils.server.js'\n\nconst MAX_CACHE_FILE_SIZE = 3 * 1024 * 1024 // 3MB in bytes\nconst cacheDir = resolveCacheDir()\nconst log = logger('epic:cache')\n\n// Throttle repeated Sentry reports for corrupted cache files to reduce noise\nconst corruptedReportThrottle = remember(\n\t'epic:cache:corruption-throttle',\n\t() => new LRUCache<string, number>({ max: 2000, ttl: 60_000 }),\n)\n\n// Format cache time helper function (copied from @epic-web/cachified for consistency)\nfunction formatCacheTime(\n\tmetadata: any,\n\tformatDuration: (ms: number) => string,\n): string {\n\tconst ttl = metadata?.ttl\n\tif (ttl === undefined || ttl === Infinity) return 'forever'\n\treturn formatDuration(ttl)\n}\n\n// Default duration formatter (copied from @epic-web/cachified for consistency)\nfunction defaultFormatDuration(ms: number): string {\n\tif (ms < 1000) return `${Math.round(ms)}ms`\n\tif (ms < 60000) return `${Math.round(ms / 1000)}s`\n\tif (ms < 3600000) return `${Math.round(ms / 60000)}m`\n\treturn `${Math.round(ms / 3600000)}h`\n}\n\n/**\n * Creates a cachified reporter that integrates with the Epic Workshop logger system.\n * Uses the pattern `epic:cache:{name-of-cache}` for logger namespaces.\n * Only logs when the specific cache namespace is enabled via NODE_DEBUG.\n */\nexport function epicCacheReporter<Value>({\n\tformatDuration = defaultFormatDuration,\n\tperformance = globalThis.performance || Date,\n}: {\n\tformatDuration?: (ms: number) => string\n\tperformance?: Pick<typeof Date, 'now'>\n} = {}): CreateReporter<Value> {\n\treturn ({ key, fallbackToCache, forceFresh, metadata, cache }) => {\n\t\t// Determine cache name for logger namespace\n\t\tconst cacheName =\n\t\t\tcache.name || cache.toString().replace(/^\\[object (.*?)]$/, '$1')\n\n\t\t// Create logger with epic:cache:{name} pattern\n\t\t// Extract a reasonable cache name from longer descriptions\n\t\tlet loggerSuffix = 'unknown'\n\t\tif (cacheName.includes('(') && cacheName.includes(')')) {\n\t\t\t// Extract name from \"Filesystem cache (CacheName)\" format\n\t\t\tconst match = cacheName.match(/\\(([^)]+)\\)/)\n\t\t\tloggerSuffix = (match?.[1] ?? 'unknown').toLowerCase()\n\t\t} else if (cacheName === 'LRUCache') {\n\t\t\t// For LRU caches, we can't determine the name from the cache object alone\n\t\t\tloggerSuffix = 'lru'\n\t\t} else {\n\t\t\tloggerSuffix = cacheName.toLowerCase()\n\t\t}\n\n\t\tconst cacheLog = log.logger(loggerSuffix)\n\n\t\tlet freshValue: unknown\n\t\tlet getFreshValueStartTs: number\n\t\tlet refreshValueStartTS: number\n\n\t\treturn (event) => {\n\t\t\tswitch (event.name) {\n\t\t\t\tcase 'getCachedValueStart': {\n\t\t\t\t\tcacheLog(`Starting cache lookup for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueEmpty': {\n\t\t\t\t\tcacheLog(`Cache miss for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueSuccess': {\n\t\t\t\t\tcacheLog(`Cache hit for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'done': {\n\t\t\t\t\tcacheLog(`Cache operation done for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueRead': {\n\t\t\t\t\tcacheLog(`Read cached value for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueHookPending': {\n\t\t\t\t\tcacheLog(`Waiting for ongoing fetch for fresh value for ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueOutdated': {\n\t\t\t\t\tcacheLog(`Cached value for ${key} is outdated`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'checkCachedValueErrorObj': {\n\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t`check failed for cached value of ${key}\\nReason: ${event.reason}.\\nDeleting the cache key and trying to get a fresh value.`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'checkFreshValueErrorObj': {\n\t\t\t\t\tlog.error(\n\t\t\t\t\t\t`check failed for fresh value of ${key}\\nReason: ${event.reason}.`,\n\t\t\t\t\t\tfreshValue,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueCacheFallback': {\n\t\t\t\t\tcacheLog(\n\t\t\t\t\t\t`Falling back to cached value for ${key} due to error getting fresh value.`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'checkCachedValueError': {\n\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t`check failed for cached value of ${key}\\nReason: ${event.reason}.\\nDeleting the cache key and trying to get a fresh value.`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getCachedValueError': {\n\t\t\t\t\tlog.error(\n\t\t\t\t\t\t`error with cache at ${key}. Deleting the cache key and trying to get a fresh value.`,\n\t\t\t\t\t\tevent.error,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueError': {\n\t\t\t\t\tlog.error(\n\t\t\t\t\t\t`getting a fresh value for ${key} failed`,\n\t\t\t\t\t\t{ fallbackToCache, forceFresh },\n\t\t\t\t\t\tevent.error,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueStart': {\n\t\t\t\t\tgetFreshValueStartTs = performance.now()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'writeFreshValueSuccess': {\n\t\t\t\t\tconst totalTime = performance.now() - getFreshValueStartTs\n\t\t\t\t\tif (event.written) {\n\t\t\t\t\t\tcacheLog(\n\t\t\t\t\t\t\t`Updated the cache value for ${key}.`,\n\t\t\t\t\t\t\t`Getting a fresh value for this took ${formatDuration(\n\t\t\t\t\t\t\t\ttotalTime,\n\t\t\t\t\t\t\t)}.`,\n\t\t\t\t\t\t\t`Caching for ${formatCacheTime(\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t\tformatDuration,\n\t\t\t\t\t\t\t)} in ${cacheName}.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcacheLog(\n\t\t\t\t\t\t\t`Not updating the cache value for ${key}.`,\n\t\t\t\t\t\t\t`Getting a fresh value for this took ${formatDuration(\n\t\t\t\t\t\t\t\ttotalTime,\n\t\t\t\t\t\t\t)}.`,\n\t\t\t\t\t\t\t`Thereby exceeding caching time of ${formatCacheTime(\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t\tformatDuration,\n\t\t\t\t\t\t\t)}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'writeFreshValueError': {\n\t\t\t\t\tlog.error(`error setting cache: ${key}`, event.error)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'getFreshValueSuccess': {\n\t\t\t\t\tfreshValue = event.value\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'checkFreshValueError': {\n\t\t\t\t\tlog.error(\n\t\t\t\t\t\t`check failed for fresh value of ${key}\\nReason: ${event.reason}.`,\n\t\t\t\t\t\tfreshValue,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'refreshValueStart': {\n\t\t\t\t\trefreshValueStartTS = performance.now()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'refreshValueSuccess': {\n\t\t\t\t\tcacheLog(\n\t\t\t\t\t\t`Background refresh for ${key} successful.`,\n\t\t\t\t\t\t`Getting a fresh value for this took ${formatDuration(\n\t\t\t\t\t\t\tperformance.now() - refreshValueStartTS,\n\t\t\t\t\t\t)}.`,\n\t\t\t\t\t\t`Caching for ${formatCacheTime(\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\tformatDuration,\n\t\t\t\t\t\t)} in ${cacheName}.`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'refreshValueError': {\n\t\t\t\t\tlog.error(`Background refresh for ${key} failed.`, event.error)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\t// @ts-expect-error Defensive programming: log unknown events for debugging\n\t\t\t\t\tcacheLog(`Unknown cache event \"${event.name}\" for key ${key}`)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport const solutionAppCache =\n\tmakeSingletonFsCache<SolutionApp>('SolutionAppCache')\nexport const problemAppCache =\n\tmakeSingletonFsCache<ProblemApp>('ProblemAppCache')\nexport const exampleAppCache =\n\tmakeSingletonFsCache<ExampleApp>('ExampleAppCache')\nexport const playgroundAppCache =\n\tmakeSingletonFsCache<PlaygroundApp>('PlaygroundAppCache')\nexport const diffCodeCache = makeSingletonFsCache<string>('DiffCodeCache')\nexport const diffFilesCache = makeSingletonFsCache<string>('DiffFilesCache')\nexport const copyUnignoredFilesCache = makeSingletonCache<string>(\n\t'CopyUnignoredFilesCache',\n)\nexport const compiledMarkdownCache = makeSingletonFsCache<string>(\n\t'CompiledMarkdownCache',\n)\nexport const compiledCodeCache = makeSingletonCache<string>('CompiledCodeCache')\nexport const ogCache = makeSingletonCache<string>('OgCache')\nexport const compiledInstructionMarkdownCache = makeSingletonFsCache<{\n\tcode: string\n\ttitle: string | null\n\tepicVideoEmbeds: Array<string>\n}>('CompiledInstructionMarkdownCache')\nexport const dirModifiedTimeCache = makeSingletonCache<number>(\n\t'DirModifiedTimeCache',\n)\nexport const connectionCache = makeSingletonCache<boolean>('ConnectionCache')\nexport const checkForUpdatesCache = makeSingletonCache<{\n\tupdatesAvailable: boolean\n\tlocalCommit: string\n\tremoteCommit: string\n\tdiffLink: string | null\n}>('CheckForUpdatesCache')\nexport const notificationsCache =\n\tmakeSingletonCache<Array<Notification>>('NotificationsCache')\nexport const directoryEmptyCache = makeSingletonCache<boolean>(\n\t'DirectoryEmptyCache',\n)\n\nexport const discordCache = makeSingletonFsCache('DiscordCache')\nexport const epicApiCache = makeSingletonFsCache('EpicApiCache')\n\nexport function makeGlobalFsCache<CacheEntryType>(name: string) {\n\treturn remember(`global-${name}`, () => {\n\t\tconst cacheInstanceDir = path.join(cacheDir, 'global', name)\n\n\t\tconst fsCache: C.Cache<CacheEntryType> = {\n\t\t\tname: `Filesystem cache (global-${name})`,\n\t\t\tasync get(key) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = await fsExtra.stat(filePath)\n\t\t\t\t\tif (stats.size > MAX_CACHE_FILE_SIZE) {\n\t\t\t\t\t\tconst sizeInMB = (stats.size / (1024 * 1024)).toFixed(2)\n\t\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t\t`Skipping large cache file ${filePath} (${sizeInMB}MB > 3MB limit). ` +\n\t\t\t\t\t\t\t\t`Consider clearing \"${name}\" cache for key: ${key}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn null\n\t\t\t\t\t}\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\tif (\n\t\t\t\t\t\terror instanceof Error &&\n\t\t\t\t\t\t'code' in error &&\n\t\t\t\t\t\terror.code === 'ENOENT'\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn null\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst data = await readJSONWithRetries(filePath)\n\t\t\t\tif (data?.entry) return data.entry\n\t\t\t\treturn null\n\t\t\t},\n\t\t\tasync set(key, entry) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\t\t\t\tconst tempPath = `${filePath}.tmp`\n\t\t\t\tawait fsExtra.ensureDir(path.dirname(filePath))\n\t\t\t\tawait fsExtra.writeJSON(tempPath, { key, entry })\n\t\t\t\tawait fsExtra.move(tempPath, filePath, { overwrite: true })\n\t\t\t},\n\t\t\tasync delete(key) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\t\t\t\tawait fsExtra.remove(filePath)\n\t\t\t},\n\t\t}\n\n\t\treturn fsCache\n\t})\n}\n\nexport const githubCache = makeGlobalFsCache('GitHubCache')\n\nasync function readJsonFilesInDirectory(\n\tdir: string,\n): Promise<Record<string, any>> {\n\tconst files = await fsExtra.readdir(dir)\n\tconst entries = await Promise.all(\n\t\tfiles\n\t\t\t.filter((file) => {\n\t\t\t\t// Filter out system files that should not be parsed as JSON\n\t\t\t\tconst lowercaseFile = file.toLowerCase()\n\t\t\t\treturn (\n\t\t\t\t\t!lowercaseFile.startsWith('.ds_store') &&\n\t\t\t\t\t!lowercaseFile.startsWith('.') &&\n\t\t\t\t\t!lowercaseFile.includes('thumbs.db')\n\t\t\t\t)\n\t\t\t})\n\t\t\t.map(async (file) => {\n\t\t\t\tconst filePath = path.join(dir, file)\n\t\t\t\tconst stats = await fsExtra.stat(filePath)\n\t\t\t\tif (stats.isDirectory()) {\n\t\t\t\t\tconst subEntries = await readJsonFilesInDirectory(filePath)\n\t\t\t\t\treturn [file, subEntries]\n\t\t\t\t} else {\n\t\t\t\t\t// Check file size before attempting to read JSON\n\t\t\t\t\tif (stats.size > MAX_CACHE_FILE_SIZE) {\n\t\t\t\t\t\tconst sizeInMB = (stats.size / (1024 * 1024)).toFixed(2)\n\t\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t\t`Skipping large cache file ${filePath} (${sizeInMB}MB > 3MB limit). ` +\n\t\t\t\t\t\t\t\t`Consider clearing cache or excluding this file type from the admin interface.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tfile,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\terror: `File too large (${sizeInMB}MB > 3MB limit)`,\n\t\t\t\t\t\t\t\tsize: stats.size,\n\t\t\t\t\t\t\t\tskipped: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\n\t\t\t\t\tconst data = await readJSONWithRetries(filePath)\n\t\t\t\t\tif (data) {\n\t\t\t\t\t\treturn [file, { ...data, size: stats.size, filepath: filePath }]\n\t\t\t\t\t}\n\n\t\t\t\t\treturn [file, null]\n\t\t\t\t}\n\t\t\t}),\n\t)\n\treturn Object.fromEntries(entries)\n}\n\n// Helper to read JSON with a couple retries; deletes corrupted files and warns\nasync function readJSONWithRetries(filePath: string): Promise<any | null> {\n\tconst maxRetries = 3\n\tconst baseDelay = 10\n\tfor (let attempt = 0; attempt <= maxRetries; attempt++) {\n\t\ttry {\n\t\t\treturn await fsExtra.readJSON(filePath)\n\t\t} catch (error: unknown) {\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\t'code' in error &&\n\t\t\t\t(error as NodeJS.ErrnoException).code === 'ENOENT'\n\t\t\t) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst isJsonParseError =\n\t\t\t\terror instanceof SyntaxError ||\n\t\t\t\t(error instanceof Error && error.message.includes('JSON'))\n\n\t\t\tif (isJsonParseError) {\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\tconst delay = baseDelay * Math.pow(2, attempt)\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`JSON parsing error on attempt ${attempt + 1}/${maxRetries + 1} for ${filePath}, retrying in ${delay}ms...`,\n\t\t\t\t\t)\n\t\t\t\t\tawait new Promise((r) => setTimeout(r, delay))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Final attempt failed: optionally report and delete file\n\t\t\t\tif (getEnv().SENTRY_DSN && getEnv().EPICSHOP_IS_PUBLISHED) {\n\t\t\t\t\tconst throttleKey = `readJSON:${md5(filePath)}`\n\t\t\t\t\tif (!corruptedReportThrottle.has(throttleKey)) {\n\t\t\t\t\t\tcorruptedReportThrottle.set(throttleKey, Date.now())\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst Sentry = await import('@sentry/react-router')\n\t\t\t\t\t\t\tSentry.withScope((scope) => {\n\t\t\t\t\t\t\t\tscope.setLevel('warning')\n\t\t\t\t\t\t\t\tscope.setTag('error_type', 'corrupted_cache_file')\n\t\t\t\t\t\t\t\tscope.setExtra('filePath', filePath)\n\t\t\t\t\t\t\t\tscope.setExtra('errorMessage', (error as Error).message)\n\t\t\t\t\t\t\t\tscope.setExtra('retryAttempts', attempt)\n\t\t\t\t\t\t\t\tSentry.captureException(error)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t} catch (sentryError) {\n\t\t\t\t\t\t\tconsole.error('Failed to log to Sentry:', sentryError)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Always delete corrupted files so subsequent reads can refetch\n\t\t\t\ttry {\n\t\t\t\t\tawait fsExtra.remove(filePath)\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`Deleted corrupted cache file after ${attempt + 1} attempts: ${filePath}`,\n\t\t\t\t\t)\n\t\t\t\t} catch (deleteError) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Failed to delete corrupted cache file ${filePath}:`,\n\t\t\t\t\t\tdeleteError,\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\t// Other errors: do not retry\n\t\t\tthrow error\n\t\t}\n\t}\n\n\treturn null\n}\n\nconst CacheEntrySchema = z.object({\n\tkey: z.string(),\n\tentry: z.object({\n\t\tvalue: z.unknown(),\n\t\tmetadata: z.object({\n\t\t\tcreatedTime: z.number(),\n\t\t\t// Stored JSON may serialize Infinity as null; allow number | null | undefined\n\t\t\tttl: z.number().nullable().optional(),\n\t\t\t// Some entries may omit swr; allow optional\n\t\t\tswr: z.number().optional(),\n\t\t}),\n\t}),\n\tsize: z.number().optional(), // File size in bytes\n\tfilepath: z.string().optional(), // Full filesystem path to the cache file\n})\n\n// Schema for files that were skipped due to size limits\nconst SkippedFileSchema = z.object({\n\terror: z.string(),\n\tsize: z.number(),\n\tskipped: z.literal(true),\n})\n\n// Combined schema that can handle both cache entries and skipped files\nconst CacheFileSchema = z.union([CacheEntrySchema, SkippedFileSchema])\n\ntype CacheEntryType = z.infer<typeof CacheEntrySchema>\n\nexport const WorkshopCacheSchema = z\n\t.record(z.record(z.record(CacheFileSchema)))\n\t.transform((workshopCaches) => {\n\t\ttype CacheEntryWithFilename = CacheEntryType & { filename: string }\n\t\ttype SkippedFileWithFilename = {\n\t\t\tfilename: string\n\t\t\terror: string\n\t\t\tsize: number\n\t\t\tskipped: true\n\t\t}\n\t\ttype Cache = {\n\t\t\tname: string\n\t\t\tentries: Array<CacheEntryWithFilename>\n\t\t\tskippedFiles?: Array<SkippedFileWithFilename>\n\t\t}\n\n\t\tconst cachesArray: Array<{\n\t\t\tworkshopId: string\n\t\t\tcaches: Array<Cache>\n\t\t}> = []\n\n\t\tfor (const [workshopId, caches] of Object.entries(workshopCaches)) {\n\t\t\tconst cachesInDir: Array<Cache> = []\n\t\t\tfor (const [cacheName, entriesObj] of Object.entries(caches)) {\n\t\t\t\tconst entries: Array<CacheEntryWithFilename> = []\n\t\t\t\tconst skippedFiles: Array<SkippedFileWithFilename> = []\n\n\t\t\t\tfor (const [key, value] of Object.entries(entriesObj)) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tvalue &&\n\t\t\t\t\t\ttypeof value === 'object' &&\n\t\t\t\t\t\t'skipped' in value &&\n\t\t\t\t\t\tvalue.skipped\n\t\t\t\t\t) {\n\t\t\t\t\t\t// This is a skipped file\n\t\t\t\t\t\tskippedFiles.push({\n\t\t\t\t\t\t\tfilename: key,\n\t\t\t\t\t\t\terror: value.error as string,\n\t\t\t\t\t\t\tsize: value.size as number,\n\t\t\t\t\t\t\tskipped: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is a regular cache entry\n\t\t\t\t\t\tentries.push({ ...(value as CacheEntryType), filename: key })\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst cache: Cache = { name: cacheName, entries }\n\t\t\t\tif (skippedFiles.length > 0) {\n\t\t\t\t\tcache.skippedFiles = skippedFiles\n\t\t\t\t}\n\t\t\t\tcachesInDir.push(cache)\n\t\t\t}\n\t\t\tcachesArray.push({ workshopId, caches: cachesInDir })\n\t\t}\n\n\t\treturn cachesArray\n\t})\n\nexport async function getAllWorkshopCaches() {\n\tconst files = await readJsonFilesInDirectory(cacheDir)\n\t// Exclude the global directory from workshop caches\n\tconst { global, ...workshopCaches } = files\n\tconst parseResult = WorkshopCacheSchema.safeParse(workshopCaches)\n\tif (!parseResult.success) {\n\t\tlog.error('Failed to parse workshop caches:', parseResult.error)\n\t\treturn []\n\t}\n\treturn parseResult.data\n}\n\nexport async function globalCacheDirectoryExists(): Promise<boolean> {\n\tconst globalCacheDir = path.join(cacheDir, 'global')\n\treturn await fsExtra.exists(globalCacheDir)\n}\n\nexport async function getGlobalCaches() {\n\tconst globalCacheDir = path.join(cacheDir, 'global')\n\tif (!(await fsExtra.exists(globalCacheDir))) {\n\t\treturn []\n\t}\n\n\tconst files = await readJsonFilesInDirectory(globalCacheDir)\n\tconst parseResult = WorkshopCacheSchema.safeParse({ global: files })\n\tif (!parseResult.success) {\n\t\tlog.error('Failed to parse global caches:', parseResult.error)\n\t\treturn []\n\t}\n\treturn parseResult.data.map((workshopCache) => ({\n\t\t...workshopCache,\n\t\tworkshopId: 'global',\n\t}))\n}\n\nexport async function getWorkshopFileCaches() {\n\tconst workshopCacheDir = path.join(\n\t\tcacheDir,\n\t\tgetEnv().EPICSHOP_WORKSHOP_INSTANCE_ID,\n\t)\n\tconst caches = readJsonFilesInDirectory(workshopCacheDir)\n\treturn caches\n}\n\nexport async function readEntryByPath(cacheFilePath: string) {\n\tconst filePath = path.join(cacheDir, cacheFilePath)\n\tconst data = await readJSONWithRetries(filePath)\n\treturn data?.entry ?? null\n}\n\nexport async function deleteCache() {\n\tif (getEnv().EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (await fsExtra.exists(cacheDir)) {\n\t\t\tawait fsExtra.remove(cacheDir)\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(`Error deleting the cache in ${cacheDir}`, error)\n\t}\n}\n\nexport async function deleteCacheEntry(cacheFilePath: string) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tconst filePath = path.join(cacheDir, cacheFilePath)\n\t\tawait fsExtra.remove(filePath)\n\t} catch (error) {\n\t\tconsole.error(`Error deleting cache entry ${cacheFilePath}:`, error)\n\t}\n}\n\nexport async function deleteWorkshopCache(\n\tworkshopId: string,\n\tcacheName?: string,\n) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (cacheName) {\n\t\t\t// Delete specific cache within workshop\n\t\t\tconst cachePath = path.join(cacheDir, workshopId, cacheName)\n\t\t\tif (await fsExtra.exists(cachePath)) {\n\t\t\t\tawait fsExtra.remove(cachePath)\n\t\t\t}\n\t\t} else {\n\t\t\t// Delete entire workshop cache directory\n\t\t\tconst workshopCachePath = path.join(cacheDir, workshopId)\n\t\t\tif (await fsExtra.exists(workshopCachePath)) {\n\t\t\t\tawait fsExtra.remove(workshopCachePath)\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t`Error deleting workshop cache ${workshopId}/${cacheName || 'all'}:`,\n\t\t\terror,\n\t\t)\n\t}\n}\n\nexport async function updateCacheEntry(cacheFilePath: string, newEntry: any) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tconst filePath = path.join(cacheDir, cacheFilePath)\n\t\tconst existingData = await readJSONWithRetries(filePath)\n\t\tif (!existingData) {\n\t\t\tthrow new Error(`Cache file does not exist: ${cacheFilePath}`)\n\t\t}\n\n\t\tconst updatedData = {\n\t\t\t...existingData,\n\t\t\tentry: {\n\t\t\t\t...existingData.entry,\n\t\t\t\tvalue: newEntry,\n\t\t\t\tmetadata: {\n\t\t\t\t\t...existingData.entry.metadata,\n\t\t\t\t\tcreatedTime: Date.now(), // Update timestamp\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tawait fsExtra.writeJSON(filePath, updatedData)\n\t\treturn updatedData.entry\n\t} catch (error) {\n\t\tconsole.error(`Error updating cache entry ${cacheFilePath}:`, error)\n\t\tthrow error\n\t}\n}\n\nexport function makeSingletonCache<CacheEntryType>(name: string) {\n\treturn remember(name, () => {\n\t\tconst lruInstance = new LRUCache<string, CacheEntry<CacheEntryType>>({\n\t\t\tmax: 1000,\n\t\t})\n\n\t\tconst lru = {\n\t\t\tname,\n\t\t\tset: (key, value) => {\n\t\t\t\tconst ttl = C.totalTtl(value.metadata)\n\t\t\t\tlruInstance.set(key, value, {\n\t\t\t\t\tttl: ttl === Infinity ? undefined : ttl,\n\t\t\t\t\tstart: value.metadata.createdTime,\n\t\t\t\t})\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tget: (key) => lruInstance.get(key),\n\t\t\tdelete: (key) => lruInstance.delete(key),\n\t\t} satisfies C.Cache<CacheEntryType>\n\n\t\treturn lru\n\t})\n}\n\nexport function makeSingletonFsCache<CacheEntryType>(name: string) {\n\treturn remember(name, () => {\n\t\tconst cacheInstanceDir = path.join(\n\t\t\tcacheDir,\n\t\t\tgetEnv().EPICSHOP_WORKSHOP_INSTANCE_ID,\n\t\t\tname,\n\t\t)\n\n\t\tconst fsCache: C.Cache<CacheEntryType> = {\n\t\t\tname: `Filesystem cache (${name})`,\n\t\t\tasync get(key) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\n\t\t\t\t// Check file size before attempting to read\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = await fsExtra.stat(filePath)\n\t\t\t\t\tif (stats.size > MAX_CACHE_FILE_SIZE) {\n\t\t\t\t\t\tconst sizeInMB = (stats.size / (1024 * 1024)).toFixed(2)\n\t\t\t\t\t\tlog.warn(\n\t\t\t\t\t\t\t`Skipping large cache file ${filePath} (${sizeInMB}MB > 3MB limit). ` +\n\t\t\t\t\t\t\t\t`Consider clearing \"${name}\" cache for key: ${key}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn null\n\t\t\t\t\t}\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\tif (\n\t\t\t\t\t\terror instanceof Error &&\n\t\t\t\t\t\t'code' in error &&\n\t\t\t\t\t\terror.code === 'ENOENT'\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn null\n\t\t\t\t\t}\n\t\t\t\t\t// For other stat errors, continue with the read attempt\n\t\t\t\t}\n\n\t\t\t\t// Use the shared helper which retries and deletes corrupted files\n\t\t\t\tconst data = await readJSONWithRetries(filePath)\n\t\t\t\tif (data?.entry) return data.entry\n\t\t\t\treturn null\n\n\t\t\t\t// This should never be reached, but just in case\n\t\t\t\treturn null\n\t\t\t},\n\t\t\tasync set(key, entry) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\t\t\t\tconst tempPath = `${filePath}.tmp`\n\t\t\t\tawait fsExtra.ensureDir(path.dirname(filePath))\n\t\t\t\t// Write to temp file first, then atomically move to final location\n\t\t\t\t// This prevents race conditions where readers see partially written JSON files\n\t\t\t\tawait fsExtra.writeJSON(tempPath, { key, entry })\n\t\t\t\tawait fsExtra.move(tempPath, filePath, { overwrite: true })\n\t\t\t},\n\t\t\tasync delete(key) {\n\t\t\t\tconst filePath = path.join(cacheInstanceDir, md5(key))\n\t\t\t\tawait fsExtra.remove(filePath)\n\t\t\t},\n\t\t}\n\n\t\treturn fsCache\n\t})\n}\n\n/**\n * This wraps @epic-web/cachified to add a few handy features:\n *\n * 1. Automatic timing for timing headers\n * 2. Automatic force refresh based on the request and enhancement of forceFresh\n * to support comma-separated keys to force\n * 3. Offline fallback support. If a fallback is given and we are detected to be\n * offline, then the cached value is used regardless of whether it's expired and\n * if one is not present then the given fallback will be used.\n */\nexport async function cachified<Value>({\n\trequest,\n\ttimings,\n\tkey,\n\ttimingKey = key.length > 18 ? `${key.slice(0, 7)}...${key.slice(-8)}` : key,\n\tofflineFallbackValue,\n\t...options\n}: Omit<C.CachifiedOptions<Value>, 'forceFresh'> & {\n\trequest?: Request\n\ttimings?: Timings\n\tforceFresh?: boolean | string\n\ttimingKey?: string\n\tofflineFallbackValue?: Value\n}): Promise<Value> {\n\tif (offlineFallbackValue !== undefined) {\n\t\tconst isOnline = await checkConnection({ request, timings })\n\t\tif (!isOnline) {\n\t\t\tlog.warn(\n\t\t\t\t`Offline: using cached value for ${key} or offline fallback if no cache is present`,\n\t\t\t)\n\t\t\tconst cacheEntry = await options.cache.get(key)\n\t\t\treturn cacheEntry?.value ?? offlineFallbackValue\n\t\t}\n\t}\n\tconst forceFresh = await shouldForceFresh({\n\t\tforceFresh: options.forceFresh,\n\t\trequest,\n\t\tkey,\n\t})\n\treturn C.cachified(\n\t\t{\n\t\t\t...options,\n\t\t\tkey,\n\t\t\tforceFresh,\n\t\t},\n\t\tC.mergeReporters(\n\t\t\tcachifiedTimingReporter(timings, timingKey),\n\t\t\tepicCacheReporter(),\n\t\t),\n\t)\n}\n\nexport async function shouldForceFresh({\n\tforceFresh,\n\trequest,\n\tkey,\n}: {\n\tforceFresh?: boolean | string\n\trequest?: Request\n\tkey?: string\n}) {\n\tif (typeof forceFresh === 'boolean') return forceFresh\n\tif (typeof forceFresh === 'string' && key) {\n\t\treturn forceFresh.split(',').includes(key)\n\t}\n\n\tif (!request) return false\n\tconst fresh = new URL(request.url).searchParams.get('fresh')\n\tif (typeof fresh !== 'string') return false\n\tif (fresh === '') return true\n\tif (!key) return false\n\n\treturn fresh.split(',').includes(key)\n}\n"]}
@@ -24,8 +24,8 @@ export declare const StackBlitzConfigSchema: z.ZodObject<{
24
24
  terminalHeight?: string | undefined;
25
25
  hideNavigation?: string | undefined;
26
26
  }>;
27
- declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
28
- title: z.ZodString;
27
+ declare const PartialWorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
28
+ title: z.ZodOptional<z.ZodString>;
29
29
  subtitle: z.ZodOptional<z.ZodString>;
30
30
  instructor: z.ZodOptional<z.ZodObject<{
31
31
  name: z.ZodOptional<z.ZodString>;
@@ -43,8 +43,93 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
43
43
  𝕏?: string | undefined;
44
44
  xHandle?: string | undefined;
45
45
  }>>;
46
- epicWorkshopHost: z.ZodOptional<z.ZodString>;
47
- epicWorkshopSlug: z.ZodOptional<z.ZodString>;
46
+ product: z.ZodOptional<z.ZodObject<{
47
+ host: z.ZodOptional<z.ZodString>;
48
+ displayName: z.ZodOptional<z.ZodString>;
49
+ displayNameShort: z.ZodOptional<z.ZodString>;
50
+ slug: z.ZodOptional<z.ZodString>;
51
+ }, "strip", z.ZodTypeAny, {
52
+ host?: string | undefined;
53
+ displayName?: string | undefined;
54
+ displayNameShort?: string | undefined;
55
+ slug?: string | undefined;
56
+ }, {
57
+ host?: string | undefined;
58
+ displayName?: string | undefined;
59
+ displayNameShort?: string | undefined;
60
+ slug?: string | undefined;
61
+ }>>;
62
+ }, "strip", z.ZodTypeAny, {
63
+ title?: string | undefined;
64
+ subtitle?: string | undefined;
65
+ instructor?: {
66
+ name?: string | undefined;
67
+ avatar?: string | undefined;
68
+ 𝕏?: string | undefined;
69
+ xHandle?: string | undefined;
70
+ } | undefined;
71
+ product?: {
72
+ host?: string | undefined;
73
+ displayName?: string | undefined;
74
+ displayNameShort?: string | undefined;
75
+ slug?: string | undefined;
76
+ } | undefined;
77
+ }, {
78
+ title?: string | undefined;
79
+ subtitle?: string | undefined;
80
+ instructor?: {
81
+ name?: string | undefined;
82
+ avatar?: string | undefined;
83
+ 𝕏?: string | undefined;
84
+ xHandle?: string | undefined;
85
+ } | undefined;
86
+ product?: {
87
+ host?: string | undefined;
88
+ displayName?: string | undefined;
89
+ displayNameShort?: string | undefined;
90
+ slug?: string | undefined;
91
+ } | undefined;
92
+ }>, {
93
+ title?: string | undefined;
94
+ subtitle?: string | undefined;
95
+ instructor?: {
96
+ name?: string | undefined;
97
+ avatar?: string | undefined;
98
+ 𝕏?: string | undefined;
99
+ xHandle?: string | undefined;
100
+ } | undefined;
101
+ product?: {
102
+ host?: string | undefined;
103
+ displayName?: string | undefined;
104
+ displayNameShort?: string | undefined;
105
+ slug?: string | undefined;
106
+ } | undefined;
107
+ } & {
108
+ product: {
109
+ host: string | undefined;
110
+ displayName: string | undefined;
111
+ displayNameShort: string | undefined;
112
+ slug: string | undefined;
113
+ };
114
+ }, {
115
+ title?: string | undefined;
116
+ subtitle?: string | undefined;
117
+ instructor?: {
118
+ name?: string | undefined;
119
+ avatar?: string | undefined;
120
+ 𝕏?: string | undefined;
121
+ xHandle?: string | undefined;
122
+ } | undefined;
123
+ product?: {
124
+ host?: string | undefined;
125
+ displayName?: string | undefined;
126
+ displayNameShort?: string | undefined;
127
+ slug?: string | undefined;
128
+ } | undefined;
129
+ }>;
130
+ export type PartialWorkshopConfig = z.infer<typeof PartialWorkshopConfigSchema>;
131
+ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
132
+ title: z.ZodString;
48
133
  subdomain: z.ZodOptional<z.ZodString>;
49
134
  product: z.ZodDefault<z.ZodObject<{
50
135
  host: z.ZodDefault<z.ZodString>;
@@ -66,8 +151,8 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
66
151
  host?: string | undefined;
67
152
  displayName?: string | undefined;
68
153
  displayNameShort?: string | undefined;
69
- logo?: string | undefined;
70
154
  slug?: string | undefined;
155
+ logo?: string | undefined;
71
156
  discordChannelId?: string | undefined;
72
157
  discordTags?: string[] | undefined;
73
158
  }>>;
@@ -147,6 +232,23 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
147
232
  link?: string | undefined;
148
233
  }>, "many">>>;
149
234
  sidecarProcesses: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
235
+ subtitle: z.ZodOptional<z.ZodString>;
236
+ instructor: z.ZodOptional<z.ZodObject<{
237
+ name: z.ZodOptional<z.ZodString>;
238
+ avatar: z.ZodOptional<z.ZodString>;
239
+ 𝕏: z.ZodOptional<z.ZodString>;
240
+ xHandle: z.ZodOptional<z.ZodString>;
241
+ }, "strip", z.ZodTypeAny, {
242
+ name?: string | undefined;
243
+ avatar?: string | undefined;
244
+ 𝕏?: string | undefined;
245
+ xHandle?: string | undefined;
246
+ }, {
247
+ name?: string | undefined;
248
+ avatar?: string | undefined;
249
+ 𝕏?: string | undefined;
250
+ xHandle?: string | undefined;
251
+ }>>;
150
252
  }, "strip", z.ZodTypeAny, {
151
253
  githubRepo: string;
152
254
  githubRoot: string;
@@ -185,8 +287,6 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
185
287
  𝕏?: string | undefined;
186
288
  xHandle?: string | undefined;
187
289
  } | undefined;
188
- epicWorkshopHost?: string | undefined;
189
- epicWorkshopSlug?: string | undefined;
190
290
  subdomain?: string | undefined;
191
291
  stackBlitzConfig?: {
192
292
  title?: string | undefined;
@@ -211,18 +311,16 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
211
311
  𝕏?: string | undefined;
212
312
  xHandle?: string | undefined;
213
313
  } | undefined;
214
- epicWorkshopHost?: string | undefined;
215
- epicWorkshopSlug?: string | undefined;
216
- subdomain?: string | undefined;
217
314
  product?: {
218
315
  host?: string | undefined;
219
316
  displayName?: string | undefined;
220
317
  displayNameShort?: string | undefined;
221
- logo?: string | undefined;
222
318
  slug?: string | undefined;
319
+ logo?: string | undefined;
223
320
  discordChannelId?: string | undefined;
224
321
  discordTags?: string[] | undefined;
225
322
  } | undefined;
323
+ subdomain?: string | undefined;
226
324
  onboardingVideo?: string | string[] | undefined;
227
325
  stackBlitzConfig?: {
228
326
  title?: string | undefined;
@@ -257,9 +355,9 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
257
355
  product: {
258
356
  displayNameShort: string;
259
357
  host: string;
260
- slug: string | undefined;
261
358
  displayName: string;
262
359
  logo: string;
360
+ slug?: string | undefined;
263
361
  discordChannelId?: string | undefined;
264
362
  discordTags?: string[] | undefined;
265
363
  };
@@ -291,8 +389,6 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
291
389
  𝕏?: string | undefined;
292
390
  xHandle?: string | undefined;
293
391
  } | undefined;
294
- epicWorkshopHost?: string | undefined;
295
- epicWorkshopSlug?: string | undefined;
296
392
  subdomain?: string | undefined;
297
393
  stackBlitzConfig?: {
298
394
  title?: string | undefined;
@@ -317,18 +413,16 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
317
413
  𝕏?: string | undefined;
318
414
  xHandle?: string | undefined;
319
415
  } | undefined;
320
- epicWorkshopHost?: string | undefined;
321
- epicWorkshopSlug?: string | undefined;
322
- subdomain?: string | undefined;
323
416
  product?: {
324
417
  host?: string | undefined;
325
418
  displayName?: string | undefined;
326
419
  displayNameShort?: string | undefined;
327
- logo?: string | undefined;
328
420
  slug?: string | undefined;
421
+ logo?: string | undefined;
329
422
  discordChannelId?: string | undefined;
330
423
  discordTags?: string[] | undefined;
331
424
  } | undefined;
425
+ subdomain?: string | undefined;
332
426
  onboardingVideo?: string | string[] | undefined;
333
427
  stackBlitzConfig?: {
334
428
  title?: string | undefined;
@@ -361,6 +455,12 @@ declare const WorkshopConfigSchema: z.ZodEffects<z.ZodObject<{
361
455
  sidecarProcesses?: Record<string, string> | undefined;
362
456
  }>;
363
457
  export type WorkshopConfig = z.infer<typeof WorkshopConfigSchema>;
458
+ /**
459
+ * Parse epicshop config from an arbitrary package.json object.
460
+ * Unlike getWorkshopConfig(), this doesn't require EPICSHOP_CONTEXT_CWD
461
+ * and returns partial/optional config suitable for external repos.
462
+ */
463
+ export declare function parseEpicshopConfig(packageJson: unknown): PartialWorkshopConfig | null;
364
464
  /**
365
465
  * This used to support subdomains on localhost, but that caused too many issues.
366
466
  */
@@ -1 +1 @@
1
- {"version":3,"file":"config.server.d.ts","sourceRoot":"","sources":["../../src/config.server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;EAcjC,CAAA;AAUF,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoFvB,CAAA;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AA2BjE;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,UAE1C;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAiClD;AAED,wBAAsB,gBAAgB,CAAC,EACtC,QAAQ,EACR,KAAK,EACL,IAAI,GACJ,EAAE;IACF,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACZ,0BA0EA;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;GA0ElD"}
1
+ {"version":3,"file":"config.server.d.ts","sourceRoot":"","sources":["../../src/config.server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;EAcjC,CAAA;AAsDF,QAAA,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAnBvB;QACR,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;QACxB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;QAC/B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;QACpC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;KACxB;;;;;;;;;;;;;;;;EAgBiC,CAAA;AAEnC,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAG/E,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8EvB,CAAA;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE;;;;GAIG;AACH,wBAAgB,mBAAmB,CAClC,WAAW,EAAE,OAAO,GAClB,qBAAqB,GAAG,IAAI,CAgB9B;AA2BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,UAE1C;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAiClD;AAED,wBAAsB,gBAAgB,CAAC,EACtC,QAAQ,EACR,KAAK,EACL,IAAI,GACJ,EAAE;IACF,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACZ,0BA0EA;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;GA0ElD"}