respira/src/services/PatternCacheService.ts
Jan-Henrik Bruhn 37f80051e0 Fix build and lint errors, refactor embroidery constants
- Remove unused imports and variables across multiple files
- Fix TypeScript 'any' type annotations with proper types
- Fix React setState in effect warnings
- Create shared embroidery constants file (embroideryConstants.ts)
- Replace magic number 0x10 with named MOVE constant
- Map PyStitch constants to JS constants using registerJsModule
- Ensure PEN encoding constants remain separate and valid

All build and lint checks now pass successfully.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-06 23:55:10 +01:00

173 lines
4.6 KiB
TypeScript

import type { PesPatternData } from '../utils/pystitchConverter';
interface CachedPattern {
uuid: string;
pesData: PesPatternData;
fileName: string;
timestamp: number;
patternOffset?: { x: number; y: number };
}
const CACHE_KEY = 'brother_pattern_cache';
/**
* Convert UUID Uint8Array to hex string
*/
export function uuidToString(uuid: Uint8Array): string {
return Array.from(uuid).map(b => b.toString(16).padStart(2, '0')).join('');
}
/**
* Convert hex string to UUID Uint8Array
*/
export function stringToUuid(str: string): Uint8Array {
const bytes = new Uint8Array(16);
for (let i = 0; i < 16; i++) {
bytes[i] = parseInt(str.substr(i * 2, 2), 16);
}
return bytes;
}
export class PatternCacheService {
/**
* Save pattern to local storage with its UUID
*/
static savePattern(
uuid: string,
pesData: PesPatternData,
fileName: string,
patternOffset?: { x: number; y: number }
): void {
try {
// Convert penData Uint8Array to array for JSON serialization
const pesDataWithArrayPenData = {
...pesData,
penData: Array.from(pesData.penData) as unknown as Uint8Array,
};
const cached: CachedPattern = {
uuid,
pesData: pesDataWithArrayPenData,
fileName,
timestamp: Date.now(),
patternOffset,
};
localStorage.setItem(CACHE_KEY, JSON.stringify(cached));
console.log('[PatternCache] Saved pattern:', fileName, 'UUID:', uuid, 'Offset:', patternOffset);
} catch (err) {
console.error('[PatternCache] Failed to save pattern:', err);
// If quota exceeded, clear and try again
if (err instanceof Error && err.name === 'QuotaExceededError') {
this.clearCache();
}
}
}
/**
* Get cached pattern by UUID
*/
static getPatternByUUID(uuid: string): CachedPattern | null {
try {
const cached = localStorage.getItem(CACHE_KEY);
if (!cached) {
return null;
}
const pattern: CachedPattern = JSON.parse(cached);
// Check if UUID matches
if (pattern.uuid !== uuid) {
console.log('[PatternCache] UUID mismatch. Cached:', pattern.uuid, 'Requested:', uuid);
return null;
}
// Restore Uint8Array from array inside pesData
if (Array.isArray(pattern.pesData.penData)) {
pattern.pesData.penData = new Uint8Array(pattern.pesData.penData);
}
console.log('[PatternCache] Found cached pattern:', pattern.fileName, 'UUID:', uuid);
return pattern;
} catch (err) {
console.error('[PatternCache] Failed to retrieve pattern:', err);
return null;
}
}
/**
* Get the most recent cached pattern (regardless of UUID)
*/
static getMostRecentPattern(): CachedPattern | null {
try {
const cached = localStorage.getItem(CACHE_KEY);
if (!cached) {
return null;
}
const pattern: CachedPattern = JSON.parse(cached);
// Restore Uint8Array from array inside pesData
if (Array.isArray(pattern.pesData.penData)) {
pattern.pesData.penData = new Uint8Array(pattern.pesData.penData);
}
return pattern;
} catch (err) {
console.error('[PatternCache] Failed to retrieve pattern:', err);
return null;
}
}
/**
* Check if a pattern with the given UUID exists in cache
*/
static hasPattern(uuid: string): boolean {
const pattern = this.getMostRecentPattern();
return pattern?.uuid === uuid;
}
/**
* Delete a specific pattern by UUID
*/
static deletePattern(uuid: string): void {
try {
const cached = this.getPatternByUUID(uuid);
if (cached) {
localStorage.removeItem(CACHE_KEY);
console.log('[PatternCache] Deleted pattern with UUID:', uuid);
}
} catch (err) {
console.error('[PatternCache] Failed to delete pattern:', err);
}
}
/**
* Clear the pattern cache
*/
static clearCache(): void {
try {
localStorage.removeItem(CACHE_KEY);
console.log('[PatternCache] Cache cleared');
} catch (err) {
console.error('[PatternCache] Failed to clear cache:', err);
}
}
/**
* Get cache info for debugging
*/
static getCacheInfo(): { hasCache: boolean; fileName?: string; uuid?: string; age?: number } {
const pattern = this.getMostRecentPattern();
if (!pattern) {
return { hasCache: false };
}
return {
hasCache: true,
fileName: pattern.fileName,
uuid: pattern.uuid,
age: Date.now() - pattern.timestamp,
};
}
}