Documentation Index
Fetch the complete documentation index at: https://docs.cocobase.buzz/llms.txt
Use this file to discover all available pages before exploring further.
JavaScript SDK
Complete guide to using Cocobase with JavaScript and TypeScript applications.
Installation
npm:
yarn:
pnpm:
Quick Start
Initialize Cocobase
import { Cocobase } from "cocobase";
const db = new Cocobase({
apiKey: "YOUR_API_KEY",
projectId: "YOUR_PROJECT_ID",
baseURL: "https://api.cocobase.buzz", // Optional, defaults to this
});
Basic Operations
// List documents
const docs = await db.listDocuments("posts");
// Get single document
const doc = await db.getDocument("posts", "doc-id");
// Create document
const created = await db.createDocument("posts", {
title: "My First Post",
content: "Hello World!",
});
// Update document
await db.updateDocument("posts", "doc-id", {
title: "Updated Title",
});
// Delete document
await db.deleteDocument("posts", "doc-id");
Batch Operations
// Create multiple documents
await db.createDocuments("users", [
{ name: "Alice", email: "alice@example.com" },
{ name: "Bob", email: "bob@example.com" },
]);
// Delete multiple documents
await db.deleteDocuments("users", ["id-1", "id-2", "id-3"]);
// Update multiple documents
await db.updateDocuments("users", {
"id-1": { status: "active" },
"id-2": { status: "inactive" },
});
Counting & Aggregation
// Count documents matching a filter
const { count } = await db.countDocuments("users", {
filters: { status: "active" }
});
// Aggregate (sum, avg, min, max, count)
const result = await db.aggregateDocuments("orders", {
field: "price",
operation: "avg",
query: { filters: { status: "completed" } }
});
console.log(result.result); // average order price
Querying Data
Simple Filters
// Find active users older than 18
const users = await db.listDocuments("users", {
filters: {
status: "active",
age__gt: 18,
},
});
Operators Reference
Comparison Operators
| Operator | Filter Key | Example |
|---|
| Equal | field | { status: "active" } |
| Greater Than | field__gt | { age__gt: 18 } |
| Greater or Equal | field__gte | { age__gte: 18 } |
| Less Than | field__lt | { age__lt: 65 } |
| Less or Equal | field__lte | { age__lte: 65 } |
| Not Equal | field__ne | { status__ne: "deleted" } |
String Operators
| Operator | Filter Key | Example |
|---|
| Contains | field__contains | { title__contains: "javascript" } |
| Starts With | field__startswith | { email__startswith: "admin" } |
| Ends With | field__endswith | { domain__endswith: ".com" } |
Array Operators
| Operator | Filter Key | Example |
|---|
| In Array | field__in | { status__in: "active,pending" } |
| Not In Array | field__notin | { status__notin: "deleted,archived" } |
Sorting and Pagination
Sorting
// Sort by creation date (newest first)
const posts = await db.listDocuments("posts", {
sort: "createdAt",
order: "desc",
});
// Get page 3 (20 items per page)
const posts = await db.listDocuments("posts", {
limit: 20,
offset: 40,
});
Type Safety with TypeScript
Define Your Types
interface Book {
title: string;
author: string;
price: number;
publishedAt?: string;
}
// Typed list
const books = await db.listDocuments<Book>("books");
// Full type safety
books.forEach((doc) => {
console.log(doc.data.title); // TypeScript knows this is a string
console.log(doc.data.price); // TypeScript knows this is a number
});
// Typed single document
const book = await db.getDocument<Book>("books", "doc-id");
console.log(book.data.author);
Create Typed Documents
const newBook: Book = {
title: "Clean Code",
author: "Robert Martin",
price: 45.99,
};
const created = await db.createDocument<Book>("books", newBook);
console.log(created.id);
Authentication
Email/Password
// Register
await db.auth.register({
email: "user@example.com",
password: "securePassword123",
data: { username: "johndoe" } // optional extra fields
});
// Get user after registration
const user = await db.auth.getUser();
console.log("User ID:", user.id);
// Login
await db.auth.login({
email: "user@example.com",
password: "securePassword123",
});
// Get user after login
const loggedInUser = await db.auth.getUser();
// Logout
await db.auth.logout();
// Check current user
const currentUser = await db.auth.getCurrentUser();
OAuth
// Google OAuth (requires Google ID token)
const user = await db.auth.loginWithGoogle({
idToken: "google-id-token",
platform: "web" // or "android" / "ios"
});
Advanced Authentication
Auth Event Callbacks
// Listen to auth state changes
db.auth.onAuthEvent({
onLogin: (user, token) => {
console.log("User logged in:", user.email);
},
onLogout: () => {
console.log("User logged out");
},
onRegister: (user, token) => {
console.log("User registered:", user.email);
},
onUserUpdate: (user) => {
console.log("User updated:", user.email);
},
onTokenChange: (token) => {
console.log("Token changed:", token);
},
onAuthStateChange: (user, token) => {
console.log("Auth state changed:", user?.email);
}
});
// Remove all callbacks
db.auth.clearAuthCallbacks();
Google OAuth
const user = await db.auth.loginWithGoogle({
idToken: "google-id-token",
platform: "web" // or "mobile", "ios", "android"
});
console.log("Logged in:", user.email);
GitHub OAuth
// 1. Redirect user to GitHub OAuth URL
const githubAuthUrl = `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}`;
window.location.href = githubAuthUrl;
// 2. Handle callback with the code
const code = new URLSearchParams(window.location.search).get("code");
const user = await db.auth.loginWithGithub({
code: code,
redirectUri: "http://localhost:3000/auth/github/callback",
platform: "web"
});
console.log("Logged in:", user.email);
Role Checking
if (db.auth.hasRole("admin")) {
console.log("User is an admin");
}
List Users
const users = await db.auth.listUsers({
filters: { status: "active" },
limit: 10
});
console.log("Total users:", users.total);
Get User By ID
const user = await db.auth.getUserById("user-123");
console.log("User:", user.email);
Password Reset
// Request reset email
await db.auth.requestPasswordReset("user@example.com");
console.log("Reset email sent");
Email Verification
// Request verification email
await db.auth.requestEmailVerification();
// Verify with token from email
await db.auth.verifyEmail("verification-token-from-email");
// Resend verification email
await db.auth.resendVerificationEmail();
Two-Factor Authentication (2FA)
// Enable 2FA for current user
await db.auth.enable2FA();
console.log("2FA enabled");
// Disable 2FA
await db.auth.disable2FA();
console.log("2FA disabled");
// Send 2FA code to email
await db.auth.send2FACode("user@example.com");
// Login flow when 2FA is enabled
const result = await db.auth.login({
email: "user@example.com",
password: "password123"
});
if (result.requires_2fa) {
console.log("2FA required:", result.message);
// After user enters their code
const user = await db.auth.verify2FALogin({
email: "user@example.com",
code: "123456"
});
console.log("2FA login successful:", user.email);
} else {
console.log("Logged in:", result.user?.email);
}
Real-time Data
Watch a Collection
const watcher = db.realtime.collection("posts", { status: "active" });
// watcher is a CollectionWatcher instance
Project Broadcast
const broadcast = db.realtime.broadcast(userId, userName);
Room Chat
const room = db.realtime.room("room-id", userId, userName);
Multiplayer Game
Initialize Game Client
const game = db.realtime.game("my-game-function");
Connect to a Room
// Basic connection
await game.connect({ roomId: "game-room-1" });
// With authentication
await game.connect({
roomId: "private-game",
token: userJwtToken
});
// With metadata (sent to server on connect)
await game.connect({
roomId: "game-1",
metadata: { playerName: "John", team: "red" }
});
Listen for Events
// Listen for connection
game.on("connected", (data) => {
console.log("Connected! My player ID:", data.your_id);
});
// Listen for players joining/leaving
game.on("player_joined", (data) => {
console.log("Player joined:", data.player_id);
});
game.on("player_left", (data) => {
console.log("Player left:", data.player_id);
});
// Listen for game state updates
game.on("state", (data) => {
renderPlayers(data.players);
});
// Listen for tick events
game.on("tick", (data) => {
updateGameLoop(data);
});
// Listen for errors
game.on("error", (data) => {
console.error("Game error:", data);
});
// Listen for disconnection
game.on("disconnected", (data) => {
console.log("Disconnected:", data.reason);
});
// Listen to ALL events (wildcard)
game.on("*", ({ event, data }) => {
console.log("Event:", event, data);
});
One-time Event Listener
// Called once then automatically removed
game.once("connected", (data) => {
console.log("Connected with ID:", data.your_id);
});
Remove Event Listeners
// Remove specific listener
const unsub = game.on("player_joined", handler);
unsub(); // unsubscribe
// Remove specific listener by reference
game.off("player_joined", handler);
// Remove all listeners for an event
game.removeAllListeners("player_joined");
// Remove ALL listeners
game.removeAllListeners();
Send Actions to Server
// Send a move action
game.send({ action: "move", x: 100, y: 200 });
// Send a chat message
game.send({ action: "chat", message: "Hello!" });
// Send any custom action
game.send({ action: "shoot", angle: 45, power: 80 });
Check Connection Status
// Check if connected
if (game.isConnected) {
console.log("Connected");
}
// Get current player ID
console.log("My ID:", game.playerId);
Disconnect
// Disconnect and disable auto-reconnect
game.disconnect();
// Disconnect but keep auto-reconnect enabled
game.disconnect(false);
Auto-Reconnect
// Auto-reconnect is enabled by default with exponential backoff
// Disable it
game.setAutoReconnect(false);
// Re-enable it
game.setAutoReconnect(true);
List Game Rooms
const { rooms, total } = await db.realtime.listGameRooms();
rooms.forEach(room => {
console.log(`${room.room_id}: ${room.player_count}/${room.max_players} players`);
});
// List all rooms including private
const { rooms } = await db.realtime.listGameRooms(false);
List Rooms
const rooms = await db.realtime.listRooms();
File Storage
// Create a document with files
await db.createDocumentWithFiles(
"posts",
{ title: "Post with Image", content: "Hello!" },
{
image: file, // single file
gallery: [img1, img2] // multiple files
}
);
// Update a document with files
await db.updateDocumentWithFiles(
"users",
"user-123",
{ bio: "Updated bio" }, // optional data update
{ avatar: newAvatarFile } // optional file update
);
Error Handling
try {
const doc = await db.getDocument("posts", "non-existent-id");
} catch (error) {
if (error.code === "NOT_FOUND") {
console.log("Document not found");
} else if (error.code === "UNAUTHORIZED") {
console.log("Not authorized");
} else {
console.log("Error:", error.message);
}
}
Best Practices
1. Always Use Types
// Good
const books = await db.listDocuments<Book>("books");
// Avoid
const books = await db.listDocuments("books");
2. Always Set Limits
// Good
const posts = await db.listDocuments("posts", {
limit: 20,
});
// Bad - could return thousands
const posts = await db.listDocuments("posts");
3. Handle Errors
try {
const doc = await db.getDocument("posts", id);
return doc;
} catch (error) {
console.error("Failed to fetch:", error);
return null;
}
4. Use Environment Variables
const db = new Cocobase({
apiKey: process.env.COCOBASE_API_KEY,
});
Next Steps