# Project Understanding Guide for Cursor IDE
## Project Overview
This is a Deno-based hypermedia web application using Hono, HTMX, and Deno KV. The architecture follows a server-first approach with minimal client-side JavaScript, leveraging WebSockets for real-time updates and Alpine.js for lightweight client state management.
## Core Architecture
### Card-Based System
Every card in the system follows this exact structure:
1. Server-Side Card Class (src/cards/[card-name]/[card-name].ts)
2. Client-Side Methods (db/client/[card-name].ts)
3. HTML Template (src/cards/[card-name]/[card-name].html)
4. CSS Styles (src/cards/[card-name]/[card-name].css)
### Real-Time Updates
- WebSocket server in main.ts
- Centralized broadcast system in src/ws/broadcast.ts
- Client-side WebSocket handling in home.html
- Event-based message passing for real-time UI updates
### Data Flow
1. Client makes request (HTTP or WebSocket)
2. Server processes in main.ts
3. Operation handled by card-specific code
4. KV store updated
5. WebSocket broadcast sent
6. All clients receive update
7. UI automatically refreshes
## Card Operations
### Creating a Card
```bash
# Create a new card
curl -X POST -H "Content-Type: application/json" \\
-d '{"name":"Card Name"}' \\
http://0.0.0.0:8000/cards/info/create
```
### Reading Card Data
```bash
# Get card messages
curl "http://0.0.0.0:8000/kv/get?key=cards,info,test-user,CARD_ID"
```
### Adding Messages
```bash
# Send a message to a card
curl -X POST -H "Content-Type: application/json" \\
-d '{"cardId":"CARD_ID", "text":"Message Text"}' \\
http://0.0.0.0:8000/cards/info/message/add
```
### Deleting Messages
```bash
# Delete a specific message
curl -X POST -H "Content-Type: application/json" \\
-d '{"cardId":"CARD_ID", "messageId":"MESSAGE_ID"}' \\
http://0.0.0.0:8000/cards/info/message/delete
```
### Deleting Cards
```bash
# Delete an entire card
curl -X POST -H "Content-Type: application/json" \\
-d '{"cardId":"CARD_ID"}' \\
http://0.0.0.0:8000/cards/info/delete
```
## WebSocket Events
### Message Format
```typescript
interface WebSocketMessage {
type: "update";
key: string; // Comma-separated key parts
value: unknown; // The updated data
}
```
### Event Types
1. Card List Updates (key ends with 'list')
2. Message Updates (key contains cardId)
## Creating New Card Types
1. Create the directory structure:
```
src/cards/[card-name]/
├── [card-name].ts # Server-side card class
├── [card-name].html # Card template
└── [card-name].css # Card styles
```
2. Create the server-side card class:
```typescript
import { Card, CardState, CardKvEntry } from '../cards.ts';
export interface [CardName]State extends CardState {
// Card-specific state
}
class [CardName]Card extends Card<[CardName]State> {
protected override async loadInitialState(): Promise<void> {
// Initialize card state
}
override getState(): [CardName]State {
// Return card state
}
protected override getKvKey(): Deno.KvKey {
return ['cards', this.id, this.userId];
}
getAlpineMethods() {
return {
// Expose methods for client-side use
};
}
}
```
3. Add client-side methods in db/client/[card-name].ts:
```typescript
export function get[CardName]Methods(): [CardName]Methods {
return {
// Card-specific client methods
};
}
```
4. Create HTML template with Alpine.js bindings:
```html
<div
class="card [card-name]-card"
x-data="{
// Card-specific data
}"
x-init="init"
>
<!-- Card template -->
</div>
```
## Best Practices
1. WebSocket Updates:
- Use broadcast for all state changes
- Include full updated state in broadcasts
- Handle reconnection gracefully
2. KV Operations:
- Use atomic operations when possible
- Include timestamps for ordering
- Handle missing data gracefully
3. UI Updates:
- Use Alpine.js for reactivity
- Spread arrays to trigger updates
- Clean up event listeners
4. Error Handling:
- Log errors on both sides
- Provide user feedback
- Handle network issues gracefully
css
html
java
javascript
react
typescript
websockets
First Time Repository
TypeScript
Languages:
CSS: 22.3KB
HTML: 18.0KB
TypeScript: 29.2KB
Created: 11/29/2024
Updated: 11/29/2024