first commit

This commit is contained in:
2025-07-19 00:36:16 +02:00
commit 051c291b8c
23 changed files with 3574 additions and 0 deletions

124
src/db.ts Normal file
View File

@ -0,0 +1,124 @@
type Note = {
id: string
x: number
y: number
content: string
}
type Space = {
id: string
notes: Note[]
}
class Database {
private db: IDBDatabase | null = null
async init() {
return new Promise<void>((resolve, reject) => {
const request = indexedDB.open('palace-db', 1)
request.onerror = () => reject(request.error)
request.onsuccess = () => {
this.db = request.result
resolve()
}
request.onupgradeneeded = (event) => {
const db = (event.target as IDBOpenDBRequest).result
if (!db.objectStoreNames.contains('spaces')) {
db.createObjectStore('spaces', { keyPath: 'id' })
}
}
})
}
async getSpace(id: string): Promise<Space | undefined> {
if (!this.db) await this.init()
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction(['spaces'], 'readonly')
const store = transaction.objectStore('spaces')
const request = store.get(id)
request.onerror = () => reject(request.error)
request.onsuccess = () => resolve(request.result)
})
}
async saveSpace(space: Space): Promise<void> {
if (!this.db) await this.init()
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction(['spaces'], 'readwrite')
const store = transaction.objectStore('spaces')
const request = store.put(space)
request.onerror = () => reject(request.error)
request.onsuccess = () => resolve()
})
}
async createSpace(id: string): Promise<Space> {
const space: Space = {
id,
notes: []
}
await this.saveSpace(space)
return space
}
async addNoteToSpace(spaceId: string, note: Note): Promise<void> {
const space = await this.getSpace(spaceId)
if (!space) {
throw new Error(`Space ${spaceId} not found`)
}
space.notes.push(note)
await this.saveSpace(space)
}
async updateNoteInSpace(spaceId: string, noteId: string, updates: Partial<Note>): Promise<void> {
const space = await this.getSpace(spaceId)
if (!space) {
throw new Error(`Space ${spaceId} not found`)
}
const noteIndex = space.notes.findIndex(n => n.id === noteId)
if (noteIndex === -1) {
throw new Error(`Note ${noteId} not found in space ${spaceId}`)
}
space.notes[noteIndex] = { ...space.notes[noteIndex], ...updates }
await this.saveSpace(space)
}
async deleteNoteFromSpace(spaceId: string, noteId: string): Promise<void> {
const space = await this.getSpace(spaceId)
if (!space) {
throw new Error(`Space ${spaceId} not found`)
}
space.notes = space.notes.filter(n => n.id !== noteId)
await this.saveSpace(space)
}
async getAllSpaceIds(): Promise<string[]> {
if (!this.db) await this.init()
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction(['spaces'], 'readonly')
const store = transaction.objectStore('spaces')
const request = store.getAllKeys()
request.onerror = () => reject(request.error)
request.onsuccess = () => resolve(request.result as string[])
})
}
async deleteSpace(id: string): Promise<void> {
if (!this.db) await this.init()
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction(['spaces'], 'readwrite')
const store = transaction.objectStore('spaces')
const request = store.delete(id)
request.onerror = () => reject(request.error)
request.onsuccess = () => resolve()
})
}
}
export const db = new Database()