Towniesystem_prompt.txt12 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}
4041```ts
42export default async function () {
43// Scheduled task code
44}
5253```ts
54export default async function (email: Email) {
55// Process email
56}
60## Val Town Standard Libraries
6162Val Town provides several hosted services and utility functions.
6364### Blob Storage
114```
115116## Val Town Utility Functions
117118Val Town provides several utility functions to help with common project tasks.
119120### Importing Utilities
176โ โโโ database/
177โ โ โโโ migrations.ts # Schema definitions
178โ โ โโโ queries.ts # DB query functions
179โ โ โโโ README.md
180โ โโโ routes/ # Route modules
195โโโ shared/
196โโโ README.md
197โโโ utils.ts # Shared types and functions
198```
199203- Main entry point should be `backend/index.ts`
204- Do NOT use Hono serveStatic middleware
205- **Static asset serving:** Use the utility functions to read and serve project files:
206```ts
207import { readFile, serveFile } from "https://esm.town/v/std/utils/index.ts";
237- Run migrations on startup or comment out for performance
238- Change table names when modifying schemas rather than altering
239- Export clear query functions with proper TypeScript typing
240241## Common Gotchas and Solutions
TownieValTownLogo.tsx1 match
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
23export function ValTownLogo () {
4return (
5<svg
TownieuseUser.tsx1 match
3const USER_ENDPOINT = "/api/user";
45export function useUser() {
6const [data, setData] = useState<any>(null);
7const [loading, setLoading] = useState(true);
TownieuseUsageStats.ts1 match
1import { useEffect } from "react";
23export function useUsageStats(messages: any[], usages: any[]) {
4useEffect(() => {
5if (!messages?.length) return;
TownieuseScrollToBottom.tsx3 matches
7*
8* @param {Array} dependencies - Array of dependencies that trigger scrolling when changed
9* @returns {Object} An object containing containerRef and scrollToBottom function
10*/
11export function useScrollToBottomContainer(dependencies = []) {
12const containerRef = useRef(null);
132829// body scroll version
30export function useScrollToBottom(dependencies = []) {
31const bottomRef = useRef(null);
32
Townieuser-summary.ts1 match
6* This includes a fallback to inference calls data when usage data is missing
7*/
8export async function getUserSummary() {
9// First, get the standard grouped data from the usage table
10const groupedUsageData = await sqlite.execute(`
TownieuseProject.tsx1 match
4const FILES_ENDPOINT = "/api/project-files";
56export function useProject(projectId: string, branchId?: string) {
7const [data, setData] = useState<any>(null);
8const [loading, setLoading] = useState(true);
TownieuseProjects.tsx1 match
3const ENDPOINT = "/api/projects-loader";
45export function useProjects() {
6const [data, setData] = useState<any>(null);
7const [loading, setLoading] = useState(true);
TownieuseLoadingFavicon.ts3 matches
1import { useEffect } from "react";
23function setLoadingFavicon() {
4document.querySelector('link[rel="icon"]').href = "/favicon-loading.svg";
5}
6function resetFavicon() {
7document.querySelector('link[rel="icon"]').href = "/favicon.svg";
8}
910export function useLoadingFavicon(loading: boolean) {
11useEffect(() => {
12if (loading) setLoadingFavicon();
TownieuseCreateProject.tsx1 match
3const ENDPOINT = "/api/create-project";
45export function useCreateProject() {
6const [data, setData] = useState<any>(null);
7const [loading, setLoading] = useState(false);