mirror of
https://github.com/bretzel-app/crumbs.git
synced 2026-10-13 04:06:57 +02:00
feat: Crumbs by Bretzel — self-hostable notes app MVP
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { db } from '$lib/server/db/index.js';
|
||||
import { notes, syncLog } from '$lib/server/db/schema.js';
|
||||
import { eq, gt } from 'drizzle-orm';
|
||||
import type { SyncQueueItem } from './idb.js';
|
||||
|
||||
/**
|
||||
* Process incoming sync changes from client.
|
||||
*/
|
||||
export async function processSyncPush(changes: SyncQueueItem[]): Promise<void> {
|
||||
for (const change of changes) {
|
||||
switch (change.operation) {
|
||||
case 'create':
|
||||
case 'update': {
|
||||
if (!change.data) continue;
|
||||
const existing = await db.select().from(notes).where(eq(notes.id, change.noteId)).get();
|
||||
|
||||
if (existing) {
|
||||
// LWW: only update if incoming timestamp is newer
|
||||
if (change.timestamp > existing.updatedAt.getTime()) {
|
||||
await db
|
||||
.update(notes)
|
||||
.set({
|
||||
...change.data,
|
||||
updatedAt: new Date(change.timestamp),
|
||||
version: existing.version + 1
|
||||
})
|
||||
.where(eq(notes.id, change.noteId));
|
||||
}
|
||||
} else if (change.operation === 'create' && change.data) {
|
||||
await db.insert(notes).values({
|
||||
id: change.noteId,
|
||||
title: change.data.title || '',
|
||||
content: change.data.content || '',
|
||||
color: change.data.color || 'default',
|
||||
pinned: change.data.pinned || false,
|
||||
archived: change.data.archived || false,
|
||||
trashed: change.data.trashed || false,
|
||||
checklistMode: change.data.checklistMode || false,
|
||||
sortOrder: change.data.sortOrder || 0,
|
||||
createdAt: new Date(change.timestamp),
|
||||
updatedAt: new Date(change.timestamp),
|
||||
version: 1
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'delete': {
|
||||
await db.delete(notes).where(eq(notes.id, change.noteId));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Log sync operation
|
||||
await db.insert(syncLog).values({
|
||||
noteId: change.noteId,
|
||||
operation: change.operation,
|
||||
timestamp: new Date(change.timestamp),
|
||||
clientId: 'default'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all notes updated since a given timestamp.
|
||||
*/
|
||||
export async function getChangesSince(sinceTimestamp: number) {
|
||||
const since = new Date(sinceTimestamp);
|
||||
const allNotes = await db.select().from(notes);
|
||||
// Filter notes updated after the timestamp
|
||||
return allNotes.filter((n) => n.updatedAt > since);
|
||||
}
|
||||
Reference in New Issue
Block a user