Phase 4.3 (Background-Sync): - webapp/src/sync-queue.ts: localStorage-basierte Queue - enqueueSync, dequeueSync, loadQueue, saveQueue, clearQueue - TypeScript mit korrekten Typen - webapp/src/EditorWithLoad.tsx: erweitert - Auto-Sync-Toggle (localStorage-Persistenz) - Online-Event-Listener: processQueue bei reconnect - Bei Auto-Sync: direkt speichern + sync - Bei Offline: in Queue, wird bei 'online' verarbeitet - Pending-Counter im UI - webapp/public/service-worker.js: Background-Sync - 'sync'-Event-Handler mit tag 'mindomat-sync' - Ruft POST /api/sync, postet Ergebnis an Clients - Browser-Support: Chrome/Edge (Background-Sync API) Tests: - tests/sync-queue.test.ts: 8 neue Tests - Startzustand, enqueue, FIFO, dequeue, clearQueue - Roundtrip, kaputtes JSON - localStorage-Mock Verifiziert: - 79/79 Tests gruen (10 neu seit v2.0.4) - Webapp tsc + build OK - EditorWithLoad funktional mit Auto-Sync-Option Pfad-Korrekturen: - vite.config.ts: ../../src/ -> ../src/ (war falsch, webapp ist nur 1 Ebene tiefer)
83 lines
2.6 KiB
TypeScript
83 lines
2.6 KiB
TypeScript
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { resolve } from 'node:path';
|
|
import { NotesApi } from '../src/notes-api-server.js';
|
|
|
|
const VAULT_PATH = process.env.MINDOMAT_VAULT_PATH ?? 'C:/GitHub/Mind-o-Mat-Vault';
|
|
|
|
// Vite-Plugin: API-Endpoints fuer Notes
|
|
function notesApiPlugin() {
|
|
return {
|
|
name: 'mindomat-notes-api',
|
|
configureServer(server: any) {
|
|
const api = new NotesApi(VAULT_PATH);
|
|
|
|
// GET /api/notes -> Liste aller Notiz-IDs
|
|
server.middlewares.use('/api/notes', (req: any, res: any, next: any) => {
|
|
if (req.method !== 'GET') return next();
|
|
try {
|
|
const notes = api.listNotes();
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify({ notes }));
|
|
} catch (err) {
|
|
res.statusCode = 500;
|
|
res.end(JSON.stringify({ error: (err as Error).message }));
|
|
}
|
|
});
|
|
|
|
// GET/PUT /api/notes/<id>
|
|
server.middlewares.use('/api/notes/', (req: any, res: any, next: any) => {
|
|
const idParam = decodeURIComponent(req.url.slice(1));
|
|
if (req.method === 'GET') {
|
|
const note = api.getNote(idParam);
|
|
if (!note) {
|
|
res.statusCode = 404;
|
|
res.end('Not found');
|
|
return;
|
|
}
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify(note));
|
|
return;
|
|
}
|
|
|
|
if (req.method === 'PUT') {
|
|
let body = '';
|
|
req.on('data', (chunk: Buffer) => { body += chunk.toString(); });
|
|
req.on('end', () => {
|
|
try {
|
|
const data = JSON.parse(body);
|
|
const result = api.saveNote(idParam, data.content ?? '');
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify(result));
|
|
} catch (err) {
|
|
res.statusCode = 500;
|
|
res.end(JSON.stringify({ error: (err as Error).message }));
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
next();
|
|
});
|
|
|
|
// POST /api/sync -> ruft mindomat sync auf
|
|
server.middlewares.use('/api/sync', (req: any, res: any, next: any) => {
|
|
if (req.method !== 'POST') return next();
|
|
api.syncVault(resolve(__dirname, '..', 'bin', 'mindomat.mjs')).then((result: { ok: boolean; message: string }) => {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
if (!result.ok) res.statusCode = 500;
|
|
res.end(JSON.stringify(result));
|
|
});
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
export default defineConfig({
|
|
plugins: [react(), notesApiPlugin()],
|
|
server: {
|
|
port: 5173,
|
|
open: true,
|
|
},
|
|
});
|