json-db
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data โ all from the browser, and deployed in milliseconds.
https://wilhelm--1d6a439a946411f080a60224a6c84d84.web.val.run
JsonDB is a powerful document database library that provides a MongoDB-like interface over Val Town's SQLite. It abstracts away the complexity of SQL while maintaining the reliability and performance of SQLite.
- ๐ Document-based: Store and query JSON documents like MongoDB
- ๐ Powerful Queries: Filter, sort, and paginate your data
- ๐ Collection Management: Create, drop, and manage collections
- ๐ Migrations: Built-in migration system for schema changes
- ๐ REST API: Ready-to-use HTTP endpoints for Val Town
- ๐ Statistics: Get insights into your database usage
- ๐ก๏ธ TypeScript: Full TypeScript support with type safety
import { jsonDb } from "./src/json-db.ts";
// Create a collection and insert a document
const user = await jsonDb.insert("users", {
name: "John Doe",
email: "john@example.com",
age: 30,
preferences: {
theme: "dark",
notifications: true
}
});
// Find documents
const users = await jsonDb.find("users", {
where: { age: { $gte: 25 } },
sort: [{ field: "name", direction: "asc" }],
limit: 10
});
// Update documents
await jsonDb.updateById("users", user.id, {
age: 31,
preferences: { theme: "light" }
});
// Delete documents
await jsonDb.deleteById("users", user.id);
// Create a collection
await jsonDb.createCollection("products");
// List all collections
const collections = await jsonDb.listCollections();
// Get collection statistics
const stats = await jsonDb.getCollectionStats("users");
// Drop a collection
await jsonDb.dropCollection("old_collection");
// Find with complex filtering
const results = await jsonDb.find("products", {
where: {
category: "electronics",
price: { $lt: 500 },
inStock: true
},
sort: [
{ field: "price", direction: "asc" },
{ field: "name", direction: "desc" }
],
limit: 20,
offset: 0
});
// Count documents
const count = await jsonDb.count("products", {
category: "electronics"
});
// Batch operations
const products = [
{ name: "Laptop", price: 999.99, category: "electronics" },
{ name: "Mouse", price: 29.99, category: "electronics" }
];
await jsonDb.insertMany("products", products);
JsonDB includes a complete REST API for Val Town. Use the HTTP example to create endpoints:
// GET /collections/users/documents
// POST /collections/users/documents
// PUT /collections/users/documents/:id
// DELETE /collections/users/documents/:id
GET /health
- Health checkGET /stats
- Database statisticsGET /collections
- List collectionsPOST /collections
- Create collectionDELETE /collections/:name
- Delete collectionGET /collections/:name/documents
- Find documentsPOST /collections/:name/documents
- Create documentGET /collections/:name/documents/:id
- Get document by IDPUT /collections/:name/documents/:id
- Update documentDELETE /collections/:name/documents/:id
- Delete document
JsonDB includes a powerful migration system:
import { migrationManager } from "./src/migrations.ts";
// Add a custom migration
migrationManager.addMigration({
version: 5,
name: "add_user_roles",
up: async () => {
// Add new fields or tables
await sqlite.execute(`
ALTER TABLE _documents
ADD COLUMN role TEXT DEFAULT 'user'
`);
},
down: async () => {
// Rollback changes
await sqlite.execute(`
ALTER TABLE _documents
DROP COLUMN role
`);
}
});
// Run migrations
const results = await migrationManager.migrate();
// Rollback to specific version
await migrationManager.rollback(3);
Check out the examples/
directory for complete examples:
basic-usage.ts
- Core functionality examplesval-town-http.ts
- REST API implementation
createCollection(name: string): Promise<boolean>
dropCollection(name: string): Promise<boolean>
listCollections(): Promise<string[]>
getCollectionStats(name: string): Promise<CollectionStats | null>
insert(collection: string, document: Document): Promise<InsertResult>
insertMany(collection: string, documents: Document[]): Promise<InsertResult[]>
find(collection: string, options?: QueryOptions): Promise<Document[]>
findById(collection: string, id: string): Promise<Document | null>
update(collection: string, where: Record<string, any>, update: Partial<Document>): Promise<UpdateResult>
updateById(collection: string, id: string, update: Partial<Document>): Promise<UpdateResult>
delete(collection: string, where: Record<string, any>): Promise<DeleteResult>
deleteById(collection: string, id: string): Promise<DeleteResult>
count(collection: string, where?: Record<string, any>): Promise<number>
getStats(): Promise<{ collections: number; totalDocuments: number; collectionsStats: CollectionStats[] }>
interface Document {
id?: string;
[key: string]: any;
}
interface QueryOptions {
limit?: number;
offset?: number;
sort?: { field: string; direction: 'asc' | 'desc' }[];
where?: Record<string, any>;
}
interface CollectionStats {
name: string;
count: number;
createdAt: string;
lastModified: string;
}
- Copy the
src/
directory to your Val Town project - Import and use:
import { jsonDb } from "./src/json-db.ts";
JsonDB is specifically designed for Val Town and uses:
- Val Town's SQLite standard library
- Proper error handling for serverless environment
- TypeScript support with Val Town types
- REST API patterns for HTTP vals
- Use indexes: The migration system creates indexes for common fields
- Batch operations: Use
insertMany()
for multiple documents - Pagination: Use
limit
andoffset
for large datasets - Collection cleanup: Drop unused collections to save space
- JSON field queries are limited to simple equality matching
- Complex aggregation queries require custom SQL
- No built-in full-text search (can be added via migrations)
- Document size limited by SQLite's TEXT storage
This library is designed for Val Town projects. Feel free to extend it with additional features or optimizations specific to your use case.
MIT License - feel free to use in your Val Town projects!