File size: 5,110 Bytes
b66ef35 c703ea3 ac7c05c fba600d 82f6d8e b66ef35 8db63ba b78dca2 82f6d8e b78dca2 565e57b 82f6d8e 565e57b 8db63ba 565e57b b78dca2 fba600d b78dca2 fba600d 565e57b 8db63ba c703ea3 565e57b c703ea3 565e57b 82f6d8e 565e57b 8db63ba 565e57b 8db63ba c703ea3 b66ef35 c703ea3 5fe1a3d c703ea3 5fe1a3d c703ea3 b66ef35 c703ea3 565e57b 02172be 6c2bc5a b66ef35 565e57b bf06454 21805fd 565e57b c703ea3 565e57b 21805fd 565e57b b66ef35 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
import { db } from './index';
import type { PicletInstance } from './schema';
import { PicletType } from '../types/picletTypes';
import type { PicletStats } from '../types';
import { generatePicletId } from '../utils/picletId';
import type { UserInfo } from '../stores/auth';
// Interface for generated piclet data (from PicletResult component)
interface GeneratedPicletData {
name: string;
imageUrl: string;
imageData?: string;
imageCaption: string;
concept: string;
imagePrompt: string;
stats: PicletStats;
createdAt: Date;
}
/**
* Convert generated piclet data to a PicletInstance
* @param data - The generated piclet data with stats and images
* @param objectName - Optional normalized object name (e.g., "eiffel tower")
* @param attributes - Optional array of variation attributes (first item is the primary variation)
* @param visualDetails - Optional additional visual details
* @param userInfo - Optional HF user info for discoverer attribution
*/
export async function generatedDataToPicletInstance(
data: GeneratedPicletData,
objectName?: string,
attributes?: string[],
visualDetails?: string,
userInfo?: UserInfo | null
): Promise<Omit<PicletInstance, 'id'>> {
if (!data.stats) {
throw new Error('Generated data must have stats to create PicletInstance');
}
const stats = data.stats as PicletStats;
// Map tier from stats to discovery rarity
let tier: string = stats.tier || 'common';
// Generate typeId using normalized object name + variation (first attribute if any)
// Variation is "canonical" if there are no attributes or if first attribute is "canonical"
const normalizedObjectName = objectName || stats.name;
const variation = attributes && attributes.length > 0 ? attributes[0] : undefined;
const typeId = generatePicletId(normalizedObjectName, variation && variation !== 'canonical' ? variation : undefined);
return {
// Basic Info
typeId: typeId,
objectName: objectName || stats.name || data.name,
nickname: stats.name || data.name,
primaryType: stats.primaryType as PicletType,
tier: tier,
// Discovery Metadata
isCanonical: false, // Will be set by server
canonicalId: undefined,
variationAttributes: attributes || [],
// Populate discoverer info from auth if available
discoveredBy: userInfo?.preferred_username || 'Player', // Legacy field
discovererSub: userInfo?.sub,
discovererUsername: userInfo?.preferred_username,
discovererName: userInfo?.name,
discovererPicture: userInfo?.picture,
discoveredAt: new Date(),
scanCount: 1,
// Collection Management
isInCollection: true, // Auto-collected when scanned
collectedAt: new Date(),
// Visual Data
imageUrl: data.imageUrl,
imageData: data.imageData,
imageCaption: data.imageCaption,
visualDetails: visualDetails || '',
concept: data.concept,
description: stats.description,
imagePrompt: data.imagePrompt
};
}
// Save a piclet instance to the database
export async function savePicletInstance(picletInstance: Omit<PicletInstance, 'id'>): Promise<number> {
const id = await db.picletInstances.add(picletInstance as any);
return id;
}
// Update a piclet instance in the database
export async function updatePicletInstance(id: number, updates: Partial<PicletInstance>): Promise<void> {
await db.picletInstances.update(id, updates);
}
// Delete a piclet instance from the database
export async function deletePicletInstance(id: number): Promise<void> {
await db.picletInstances.delete(id);
}
// Get all piclet instances
export async function getAllPicletInstances(): Promise<PicletInstance[]> {
return await db.picletInstances.toArray();
}
// Get a single piclet instance by ID
export async function getPicletInstance(id: number): Promise<PicletInstance | undefined> {
return await db.picletInstances.get(id);
}
// Get collected piclets (those that have been discovered)
export async function getCollectedPiclets(): Promise<PicletInstance[]> {
const allRecords = await db.picletInstances.toArray();
return allRecords.filter(p => p.isInCollection === true);
}
// Get canonical piclets
export async function getCanonicalPiclets(): Promise<PicletInstance[]> {
// Use filter for boolean fields to avoid index issues
const allRecords = await db.picletInstances.toArray();
return allRecords.filter(p => p.isCanonical === true);
}
// Get piclets by object name
export async function getPicletsByObjectName(objectName: string): Promise<PicletInstance[]> {
return await db.picletInstances.where('objectName').equals(objectName).toArray();
}
// Get variations of a canonical piclet
export async function getVariations(canonicalId: string): Promise<PicletInstance[]> {
return await db.picletInstances.where('canonicalId').equals(canonicalId).toArray();
}
// Update scan count
export async function updateScanCount(picletId: number): Promise<void> {
const piclet = await db.picletInstances.get(picletId);
if (piclet) {
await db.picletInstances.update(picletId, {
scanCount: (piclet.scanCount || 0) + 1
});
}
} |