thirdTimer.cursorrules12 matches
45- Ask clarifying questions when requirements are ambiguous
6- Provide complete, functional solutions rather than skeleton implementations
7- Test your logic against edge cases before presenting the final solution
8- Ensure all code follows Val Town's specific platform requirements
17- **Never bake in secrets into the code** - always use environment variables
18- Include comments explaining complex logic (avoid commenting obvious operations)
19- Follow modern ES6+ conventions and functional programming practices if possible
2021## Types of triggers
2829```ts
30export default async function (req: Request) {
31return new Response("Hello World");
32}
4243```ts
44export default async function () {
45// Scheduled task code
46}
5657```ts
58export default async function (email: Email) {
59// Process email
60}
66## Val Town Standard Libraries
6768Val Town provides several hosted services and utility functions.
6970### Blob Storage
120```
121122## Val Town Utility Functions
123124Val Town provides several utility functions to help with common project tasks.
125126### Importing Utilities
200โ โโโ database/
201โ โ โโโ migrations.ts # Schema definitions
202โ โ โโโ queries.ts # DB query functions
203โ โ โโโ README.md
204โ โโโ routes/ # Route modules
219โโโ shared/
220โโโ README.md
221โโโ utils.ts # Shared types and functions
222```
223226- Hono is the recommended API framework
227- Main entry point should be `backend/index.ts`
228- **Static asset serving:** Use the utility functions to read and serve project files:
229```ts
230import { readFile, serveFile } from "https://esm.town/v/std/utils@85-main/index.ts";
260- Run migrations on startup or comment out for performance
261- Change table names when modifying schemas rather than altering
262- Export clear query functions with proper TypeScript typing
263264## Common Gotchas and Solutions
16}
1718export default function VoiceRecorder({ onVoiceNoteCreated }: VoiceRecorderProps) {
19const [recordingState, setRecordingState] = useState<RecordingState>({
20isRecording: false,
voicemessagesVoicePlayer.tsx1 match
7}
89export default function VoicePlayer({ voiceNoteId }: VoicePlayerProps) {
10const [voiceNote, setVoiceNote] = useState<VoiceNote | null>(null);
11const [loading, setLoading] = useState(true);
voicemessagesvoicenotes.ts2 matches
150apiKey: Deno.env.get("GROQ_API_KEY") || "",
151});
152// Background transcription function
153async function transcribeAudio(voiceNoteId: string, audioBuffer: ArrayBuffer) {
154try {
155// Convert ArrayBuffer to File for OpenAI
voicemessagesShareModal.tsx1 match
9}
1011export default function ShareModal({ onSave, onCancel, isUploading }: ShareModalProps) {
12const [expirationType, setExpirationType] = useState<'none' | 'date' | 'listens'>('none');
13const [expirationDate, setExpirationDate] = useState('');
voicemessagesqueries.ts6 matches
3import type { VoiceNote } from "../../shared/types.ts";
45export async function createVoiceNote(voiceNote: Omit<VoiceNote, 'isExpired'>): Promise<void> {
6try {
7await sqlite.execute(
29}
3031export async function getVoiceNote(id: string): Promise<VoiceNote | null> {
32try {
33const result = await sqlite.execute(
68}
6970export async function incrementListenCount(id: string): Promise<void> {
71await sqlite.execute(
72`UPDATE ${TABLE_NAME} SET current_listens = current_listens + 1 WHERE id = ?`,
75}
7677export async function updateTranscription(id: string, transcription: string): Promise<void> {
78await sqlite.execute(
79`UPDATE ${TABLE_NAME} SET transcription = ? WHERE id = ?`,
82}
8384export async function deleteVoiceNote(id: string): Promise<void> {
85await sqlite.execute(
86`DELETE FROM ${TABLE_NAME} WHERE id = ?`,
89}
9091export async function getAllVoiceNotes(): Promise<VoiceNote[]> {
92try {
93const result = await sqlite.execute(`SELECT * FROM ${TABLE_NAME} ORDER BY created_at DESC`);
voicemessagesmigrations.ts1 match
3const TABLE_NAME = 'voice_notes_v1';
45export async function runMigrations() {
6try {
7// Create voice notes table
voicemessagesDashboard.tsx1 match
3import type { VoiceNote } from "../../shared/types.ts";
45export default function Dashboard() {
6const [voiceNotes, setVoiceNotes] = useState<VoiceNote[]>([]);
7const [loading, setLoading] = useState(true);
voicemessagesApp.tsx1 match
11}
1213export default function App() {
14const [currentView, setCurrentView] = useState<"recorder" | "player" | "dashboard">("recorder");
15const voiceNoteId = window.__VOICE_NOTE_ID__;
wakatime-readme-chartmain.tsx7 matches
40}
4142function App() {
43const [chartUrl, setChartUrl] = useState<string | null>(null);
4457}
5859function client() {
60createRoot(document.getElementById("root")!).render(<App />);
61}
65}
6667async function fetchWakaTimeData(): Promise<DataPoint[]> {
68const response = await fetch("https://wakatime.com/share/@load1n9/899abefd-d814-4e99-b603-e94af0305d4a.json");
69const data = await response.json();
82};
8384async function generateChart(data: DataPoint[]): Promise<string> {
85const width = 1000;
86const height = 600;
164}
165166function roundRect(
167ctx: CanvasRenderingContext2D,
168x: number,
190}
191192function roundRectTop(
193ctx: CanvasRenderingContext2D,
194x: number,
219}
220221export default async function server(request: Request): Promise<Response> {
222const url = new URL(request.url);
223