fix(settings, yjs, ux, ci): default settings, y-leveldb restart resilience, dashboard one-click open, delete error handling, Playwright CI

This commit is contained in:
2026-07-27 03:15:30 +02:00
parent 7f8695456c
commit 126277ab94
13 changed files with 129 additions and 45 deletions
+42 -13
View File
@@ -28,25 +28,54 @@ let persistence: LeveldbPersistence | null = null;
let persistenceReady: Promise<void> | null = null;
export async function initYjsPersistence(): Promise<void> {
try {
persistence = new LeveldbPersistence(PERSISTENCE_DIR);
// Set persistenceReady so getOrCreateDoc can await it
persistenceReady = (async () => {
// Wait for LevelDB to be ready
await (persistence as any).getAllDocNames();
})();
await persistenceReady;
console.log(`Yjs persistence initialized at ${PERSISTENCE_DIR}`);
} catch (err) {
console.warn('Yjs persistence failed to init (non-fatal):', err);
}
const tryInit = async (allowReset: boolean): Promise<void> => {
try {
persistence = new LeveldbPersistence(PERSISTENCE_DIR);
persistenceReady = (async () => {
// Wait for LevelDB to be ready
await (persistence as any).getAllDocNames();
})();
await persistenceReady;
console.log(`Yjs persistence initialized at ${PERSISTENCE_DIR}`);
} catch (err) {
// In dev mode the persistence dir lives under /tmp. If the previous process
// did not shut down cleanly, LevelDB can be left in a locked/corrupted state.
// Resetting the directory is acceptable because collaboration history is ephemeral.
if (allowReset && PERSISTENCE_DIR.startsWith('/tmp/')) {
console.warn(`Yjs persistence init failed, resetting ${PERSISTENCE_DIR} and retrying...`);
try {
if (persistence) {
await persistence.destroy().catch(() => {});
persistence = null;
persistenceReady = null;
}
const fs = await import('fs');
fs.rmSync(PERSISTENCE_DIR, { recursive: true, force: true });
fs.mkdirSync(PERSISTENCE_DIR, { recursive: true });
} catch (cleanupErr) {
console.warn('Yjs persistence cleanup failed:', cleanupErr);
}
return tryInit(false);
}
console.warn('Yjs persistence failed to init (running without disk persistence):', err);
persistence = null;
persistenceReady = null;
}
};
await tryInit(true);
}
export async function closeYjsPersistence(): Promise<void> {
if (persistence) {
await persistence.destroy();
try {
await persistence.destroy();
} catch (err) {
console.warn('Yjs persistence close failed (non-fatal):', err);
}
persistence = null;
}
persistenceReady = null;
}
async function getOrCreateDoc(docName: string): Promise<Y.Doc> {