P2-01: add SQLite WASM OPFS project worker
This commit is contained in:
@@ -13,6 +13,7 @@ import type {
|
||||
TaskSnapshot,
|
||||
Unsubscribe,
|
||||
} from './types'
|
||||
import { createSqliteProjectPersistence } from './projectStore'
|
||||
import { ThreeViewportAdapter } from './threeViewport'
|
||||
|
||||
const initialTree: ModelTreeItem[] = [
|
||||
@@ -49,7 +50,8 @@ const commandState = (commandId: string, activeWorkbench: WorkbenchId, selectedO
|
||||
}
|
||||
|
||||
export function createMockFacade(): BitBybitWebCadFacade {
|
||||
let state: FacadeState = { apiVersion: '0.1', activeWorkbench: 'Part Design', selectedObjectId: 'pad', document: createDocument(), task: null, lastNotice: '', diagnostics: [] }
|
||||
const projectPersistence = createSqliteProjectPersistence()
|
||||
let state: FacadeState = { apiVersion: '0.1', activeWorkbench: 'Part Design', selectedObjectId: 'pad', document: createDocument(), persistence: projectPersistence.capabilities(), task: null, lastNotice: '', diagnostics: [] }
|
||||
const listeners = new Set<FacadeListener>()
|
||||
const undoStack: FacadeState[] = []
|
||||
const redoStack: FacadeState[] = []
|
||||
@@ -106,7 +108,15 @@ export function createMockFacade(): BitBybitWebCadFacade {
|
||||
}
|
||||
emit({ type: 'command.started', commandId, context })
|
||||
if (commandId === 'new-document') commit({ ...state, document: createDocument('Untitled document'), selectedObjectId: '' })
|
||||
else if (commandId === 'save') commit({ ...state, document: { ...state.document, dirty: false, version: state.document.version + 1 } })
|
||||
else if (commandId === 'save') {
|
||||
const savedDocument = { ...state.document, dirty: false, version: state.document.version + 1 }
|
||||
commit({ ...state, document: savedDocument })
|
||||
void projectPersistence.save(savedDocument).catch((error: unknown) => {
|
||||
const diagnostic: Diagnostic = { id: `diag-${++requestSequence}`, severity: 'error', code: 'PERSISTENCE_SAVE_FAILED', message: error instanceof Error ? error.message : String(error), requestId }
|
||||
state = { ...state, diagnostics: [...state.diagnostics, diagnostic] }
|
||||
emit({ type: 'diagnostic.added', diagnostic, context }); notify('Save failed; export a recovery package')
|
||||
})
|
||||
}
|
||||
else if (commandId === 'select-object' && typeof payload?.objectId === 'string') select(payload.objectId)
|
||||
else if (featureCommands[commandId]) beginTask(commandId, { source: state.selectedObjectId || null })
|
||||
emit({ type: 'command.completed', commandId, context }); emitState(); return requestId
|
||||
@@ -118,8 +128,10 @@ export function createMockFacade(): BitBybitWebCadFacade {
|
||||
gui: { workbench: { list: () => Object.keys(workbenchDefinitions) as WorkbenchId[], getActive: () => state.activeWorkbench, setActive }, command: { getState: (commandId) => commandState(commandId, state.activeWorkbench, state.selectedObjectId), list: (workbench) => workbenchDefinitions[workbench].groups.flatMap((group) => group.commands), execute } },
|
||||
selection: { getObjectId: () => state.selectedObjectId, select, clear: () => select('') },
|
||||
task: { getActive: () => getState().task, begin: beginTask, update: (draft) => { if (state.task) state = { ...state, task: { ...state.task, draft: { ...state.task.draft, ...draft } } }; emitState() }, apply: applyTask, cancel: () => { if (state.task) state = { ...state, task: { ...state.task, status: 'cancelled' } }; emitState() } },
|
||||
project: { capabilities: () => projectPersistence.capabilities(), save: (document = getState().document) => projectPersistence.save(document), load: (documentId) => projectPersistence.load(documentId) },
|
||||
viewport: { createAdapter: () => new ThreeViewportAdapter() },
|
||||
getState, subscribe: (listener) => { listeners.add(listener); return () => { listeners.delete(listener) } }, notify,
|
||||
}
|
||||
void projectPersistence.initialize().then((nextCapabilities) => { state = { ...state, persistence: nextCapabilities }; emitState() }).catch((error: unknown) => { const diagnostic: Diagnostic = { id: `diag-${++requestSequence}`, severity: 'warning', code: 'PERSISTENCE_INIT_FAILED', message: error instanceof Error ? error.message : String(error) }; state = { ...state, diagnostics: [...state.diagnostics, diagnostic] }; emit({ type: 'diagnostic.added', diagnostic, context: { apiVersion: state.apiVersion, requestId: `req-${++requestSequence}`, documentId: state.document.id, documentVersion: state.document.version, workbench: state.activeWorkbench } }) })
|
||||
return facade
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user