sqlite_adminREADME.md1 match
7It's currently super limited (no pagination, editing data, data-type specific viewers), and is just a couple dozens lines of code over a couple different vals. Forks encouraged! Just comment on the val if you add any features that you want to share.
89To use it on your own Val Town SQLite database, [fork it](https://www.val.town/v/stevekrouse/sqlite_admin/fork) to your account.
1011It uses [basic authentication](https://www.val.town/v/pomdtr/basicAuth) with your [Val Town API Token](https://www.val.town/settings/api) as the password (leave the username field blank).
9- The **client-side entrypoint** is `/frontend/index.html`, which in turn imports `/frontend/index.tsx`, which in turn imports the React app from `/frontend/components/App.tsx`.
1011[React Hono Example](https://www.val.town/x/stevekrouse/reactHonoExample) is a fuller featured example project, with a SQLite database table, queries, client-side CSS and a favicon, and some shared code that runs on both client and server.
kanbanTestmain.tsx4 matches
26"Roboto Mono", "Roboto", "Rubik Vinyl"
27],
28database: {
29getKey: () => "kanbanTest",
30getSchemaVersion: () => 7,
31getTableName: () => {
32const key = config.database.getKey();
33const version = config.database.getSchemaVersion();
34return `${key}_tasks_${version}`;
35}
457export default async function server(request: Request): Promise<Response> {
458const { sqlite } = await import("https://esm.town/v/stevekrouse/sqlite");
459const tableName = config.database.getTableName();
460461await sqlite.execute(`
282283try {
284// Initialize database with enhanced error handling and add cache table
285await sqlite.execute(`
286CREATE TABLE IF NOT EXISTS ${KEY}_tools_${SCHEMA_VERSION} (
319`);
320321serverLog("INFO", "Database initialized successfully", {
322key: KEY,
323schemaVersion: SCHEMA_VERSION,
324});
325} catch (dbInitError) {
326serverLog("ERROR", "Database initialization failed", {
327error: dbInitError instanceof Error ? dbInitError.message : String(dbInitError),
328key: KEY,
330return new Response(
331JSON.stringify({
332error: "Database initialization failed",
333details: String(dbInitError),
334}),
549const toolRequest = agentAResponse.tool;
550551// Store the tool in the database
552const toolId = toolRequest.id || crypto.randomUUID();
553await sqlite.execute(
606const toolResponse: ToolResponse = JSON.parse(agentBContent);
607608// Store the tool request and response in the database
609const requestId = crypto.randomUUID();
610await sqlite.execute(
739const toolResponse: ToolResponse = JSON.parse(completionContent);
740741// Store the tool request and response in the database
742const requestId = toolRequest.id || crypto.randomUUID();
743await sqlite.execute(
851agentAResponse = JSON.parse(completionContent);
852853// If it's a new tool, store it in the database
854if (agentAResponse.tool) {
855const toolId = crypto.randomUUID();
HTTP101POSTrequestFormGuide1 match
99to a variable because variables lose all data every time you save a version. On Val Town there are
100two ways to store data long term. They are blob and SQlite. Both of them have 10mb on the free plan and
1011gb on pro. The difference is that blob storage is just key value while SQlite is a database. Since it
102doesn't make sense to use SQlite's data unnecessarily and it's complex enough to be its own guide,
103we're using blob storage.</p>
AlwaysHereBackendREADME.md2 matches
45* `index.ts` - this is the **entrypoint** for this whole project
6* `database/` - this contains the code for interfacing with the app's SQLite database table
78## Hono
26## CRUD API Routes
2728This app has two CRUD API routes: for reading and inserting into the messages table. They both speak JSON, which is standard. They import their functions from `/backend/database/queries.ts`. These routes are called from the React app to refresh and update data.
2930## Errors
AlwaysHereBackendREADME.md6 matches
1# Database
23This app uses [Val Town SQLite](https://docs.val.town/std/sqlite/) to manage data. Every Val Town account comes with a free SQLite database, hosted on [Turso](https://turso.tech/). This folder is broken up into two files:
45* `migrations.ts` - code to set up the database tables the app needs
6* `queries.ts` - functions to run queries against those tables, which are imported and used in the main Hono server in `/backend/index.ts`
78## Migrations
910In `backend/database/migrations.ts`, this app creates a new SQLite table `reactHonoStarter_messages` to store messages.
1112This "migration" runs once on every app startup because it's imported in `index.ts`. You can comment this line out for a slight (30ms) performance improvement on cold starts. It's left in so that users who fork this project will have the migration run correctly.
1314SQLite has much more limited support for altering existing tables as compared to other databases. Often it's easier to create new tables with the schema you want, and then copy the data over. Happily LLMs are quite good at those sort of database operations, but please reach out in the [Val Town Discord](https://discord.com/invite/dHv45uN5RY) if you need help.
1516## Queries
1718The queries file is where running the migrations happen in this app. It'd also be reasonable for that to happen in index.ts, or as is said above, for that line to be commented out, and only run when actual changes are made to your database schema.
1920The queries file exports functions to get and write data. It relies on shared types and data imported from the `/shared` directory.
2122However, you should know that SQLite has much more limited
23support for altering existing tables as compared to other databases.
24Often it's easier to create new tables with the schema you want, and then
25copy the data over. */
1import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
2import { Hono } from "npm:hono";
3import { USERS } from "../database/migrations.ts"; // Make sure migrations defines this table
45const CLIENT_ID = "your_google_client_id";
AlwaysHereindex.ts3 matches
9import userApi from "./api/user.ts";
10import googleOAuth from "./auth/googleOAuth.ts";
11import { createTables } from "./database/migrations.ts";
12const app = new Hono();
1316});
1718app.get("/setupDatabase", async c => {
19createTables();
20return c.text("Database Setup Successful");
21});
22app.route("/auth/google", googleOAuth);