feat(workspace): tabula-rasa outliner architecture, SQLite blocks/block_tags schema & echo-protected live room sync
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m12s

This commit is contained in:
sandrodach committed 2026-10-26 21:14:06 +01:00
1 parent f3b3f07e04
commit 86867b0d6f
17 files changed
+3409 -7178

No files matched your search

+1 -77
View File
@@ -602,31 +602,6 @@ export const api = {
};
},
async getDocumentCRDT(id: string): Promise<{ docId: string; state?: string; updates?: string[] }> {
return request<{ docId: string; state?: string; updates?: string[] }>(`/api/v1/documents/${id}/crdt`);
},
async saveDocumentCRDT(id: string, payload: string | { state?: string; update?: string }): Promise<{ success: boolean }> {
const body = typeof payload === 'string' ? { state: payload } : payload;
return request<{ success: boolean }>(`/api/v1/documents/${id}/crdt`, {
method: 'PUT',
body: JSON.stringify(body),
});
},
async sendDocumentAwareness(id: string, payload: any): Promise<{ success: boolean }> {
return request<{ success: boolean }>(`/api/v1/documents/${id}/awareness`, {
method: 'POST',
body: JSON.stringify(payload),
});
},
async clearDocumentAwareness(id: string): Promise<{ success: boolean }> {
return request<{ success: boolean }>(`/api/v1/documents/${id}/awareness`, {
method: 'DELETE',
});
},
async joinSSERoom(sseId: string, room: string, action: 'join' | 'leave' = 'join'): Promise<{ success: boolean }> {
return request<{ success: boolean }>('/api/v1/events/rooms', {
method: 'POST',
@@ -675,44 +650,6 @@ export const api = {
return ensureArray(res);
},
// --- DOCUMENT LOCKING ---
async getDocLock(docId: string): Promise<{ locked: boolean; lock?: DocLockInfo }> {
return request<{ locked: boolean; lock?: DocLockInfo }>(`/api/v1/documents/${docId}/lock`);
},
async lockDocument(
docId: string
): Promise<{ locked: boolean; acquired: boolean; lock?: DocLockInfo; message?: string }> {
try {
return await request<{ locked: boolean; acquired: boolean; lock?: DocLockInfo; message?: string }>(
`/api/v1/documents/${docId}/lock`,
{ method: 'POST' }
);
} catch (e: any) {
return { locked: true, acquired: false, message: e.message };
}
},
async heartbeatDocLock(docId: string): Promise<{ extended: boolean }> {
try {
return await request<{ extended: boolean }>(`/api/v1/documents/${docId}/lock/heartbeat`, {
method: 'POST',
});
} catch {
return { extended: false };
}
},
async unlockDocument(docId: string): Promise<{ unlocked: boolean }> {
try {
return await request<{ unlocked: boolean }>(`/api/v1/documents/${docId}/lock`, {
method: 'DELETE',
});
} catch {
return { unlocked: false };
}
},
// --- SPACES & REALTIME LISTS ---
async getSpaces(): Promise<Space[]> {
const res = await request<Space[]>('/api/v1/spaces');
@@ -1398,23 +1335,10 @@ export function sendWebSocketMessage(msg: any): void {
// SSE Fallback: dispatch via REST endpoints
try {
const parsed = typeof msg === 'string' ? JSON.parse(msg) : msg;
if (parsed.event === 'CRDT_UPDATE' && parsed.docId) {
api.saveDocumentCRDT(parsed.docId, { update: parsed.payload?.update }).catch(() => {});
} else if (parsed.event === 'CRDT_AWARENESS' && parsed.docId) {
api.sendDocumentAwareness(parsed.docId, parsed.payload).catch(() => {});
} else if (parsed.event === 'CRDT_LEAVE' && parsed.docId) {
api.clearDocumentAwareness(parsed.docId).catch(() => {});
if (activeSSEId) api.joinSSERoom(activeSSEId, `doc:${parsed.docId}`, 'leave').catch(() => {});
} else if (parsed.event === 'CRDT_JOIN' && parsed.docId) {
if (activeSSEId) api.joinSSERoom(activeSSEId, `doc:${parsed.docId}`, 'join').catch(() => {});
} else if (parsed.event === 'JOIN_ROOM' && parsed.room) {
if (parsed.event === 'JOIN_ROOM' && parsed.room) {
if (activeSSEId) api.joinSSERoom(activeSSEId, parsed.room, 'join').catch(() => {});
} else if (parsed.event === 'LEAVE_ROOM' && parsed.room) {
if (activeSSEId) api.joinSSERoom(activeSSEId, parsed.room, 'leave').catch(() => {});
} else if (parsed.event === 'LOCK_DOC' && parsed.docId) {
api.lockDocument(parsed.docId).catch(() => {});
} else if (parsed.event === 'UNLOCK_DOC' && parsed.docId) {
api.unlockDocument(parsed.docId).catch(() => {});
}
} catch (err) {
console.error('Error dispatching fallback REST message for SSE:', err);