this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update stale stopSseConsumer references after the stop/wipe split

Docs and comments across Rust, TypeScript, and Markdown still described the
pre-split world where stopSseConsumer drained the keepers. It hasn't for a
while — stop only flips the consumer's cancellation flag, wipeState drains
TreeKeeper / WorkspaceKeeper / InboxKeeper. Update the keeper docstrings,
FLOWS.md, the daemon example, the cabinet route comment, and the SDK
FileManager.delete JSDoc (which still said "if a parent directory is
provided" long after that became required).

Also rewrite the badly-out-of-date web section in CRATE_STRUCTURE.md:
the old layout listed a workers/ tree that no longer exists and a
SearchResults.tsx we deleted, and omitted the lib/ files and cabinet
components that actually live there now.

+56 -42
+3 -3
apps/web/src/routes/cabinet/route.lazy.tsx
··· 25 25 // no per-route wiring needed. 26 26 27 27 // SSE consumer lifecycle is handled by <OpakeProvider> below, which 28 - // calls startSseConsumer on mount and stopSseConsumer (including 29 - // `TreeKeeper::uninstall_all`) on unmount so the previous user's 30 - // `ContentKey`s / decrypted names don't linger across login. 28 + // calls startSseConsumer on mount and (on unmount) stopSseConsumer 29 + // followed by wipeState — the latter drains the keepers so the previous 30 + // user's `ContentKey`s / decrypted names don't linger across login. 31 31 32 32 // JS-side decrypted-plaintext caches (preview + readme Suspense maps) 33 33 // live at module scope in their respective components so they survive
+2 -2
crates/opake-core/src/indexer/inbox_keeper/mod.rs
··· 169 169 170 170 /// Drop every entry, clear every watcher, and reset `loaded`. 171 171 /// 172 - /// Called on `stopSseConsumer` so account switches don't leak the 173 - /// previous user's inbox into the next session's UI. 172 + /// Called on `wipeState` so account switches don't leak the previous 173 + /// user's inbox into the next session's UI. 174 174 pub fn uninstall_all(&mut self) { 175 175 self.entries.clear(); 176 176 self.watchers.clear();
+5 -3
crates/opake-core/src/indexer/tree_keeper/mod.rs
··· 164 164 /// private key from memory. The decrypted directory name cache on 165 165 /// each `DirectoryTree` is freed along with the tree itself. 166 166 /// 167 - /// Called on `stopSseConsumer` so that account switches don't leak 168 - /// a previous user's crypto material or metadata into the next 169 - /// session's address space. 167 + /// Called on `wipeState` so that account switches don't leak a 168 + /// previous user's crypto material or metadata into the next 169 + /// session's address space. `stopSseConsumer` does not drain the 170 + /// keepers — callers that need to pause streaming without forcing 171 + /// a re-bootstrap should stop the consumer without wiping. 170 172 pub fn uninstall_all(&mut self) { 171 173 self.cabinet = None; 172 174 self.workspaces.clear();
+2 -2
crates/opake-core/src/indexer/workspace_keeper/mod.rs
··· 217 217 218 218 /// Drop every entry, clear every watcher, and reset `loaded`. 219 219 /// 220 - /// Called on `stopSseConsumer` so account switches don't leak the 221 - /// previous user's workspace list into the next session's UI. 220 + /// Called on `wipeState` so account switches don't leak the previous 221 + /// user's workspace list into the next session's UI. 222 222 pub fn uninstall_all(&mut self) { 223 223 self.entries.clear(); 224 224 self.watchers.clear();
+38 -27
docs/CRATE_STRUCTURE.md
··· 173 173 174 174 web/ React SPA (Vite + TanStack Start + Tailwind + daisyUI) 175 175 src/ 176 + client.tsx SPA entry point 177 + router.tsx TanStack Router config 176 178 lib/ 177 - encoding.ts Base64/hex/fingerprint utilities 178 - atUri.ts AT-URI parsing helpers 179 - pairing.ts Device pairing (thin wrappers over @opake/sdk) 179 + atUri.ts AT-URI parsing helpers 180 + cn.ts Tailwind class merge utility 181 + directoryTree.ts Tree traversal (parent lookup, ancestor chain, path suffix) 182 + docs-registry.ts Documentation section metadata 183 + download.ts Browser file-download helpers 184 + encoding.ts Base64/hex/fingerprint utilities 185 + fileContext.ts Discriminated cabinet-vs-workspace file context 186 + format.ts Size/date/text formatters 187 + og-meta.ts Open Graph meta tag helpers 188 + pairing.ts Device pairing (thin wrappers over @opake/sdk) 189 + pdsTypes.ts Re-exports of @opake/sdk DTO types 190 + persistent-storage.ts navigator.storage persistence request 191 + profileResolution.ts Bluesky profile lookup 192 + resizeImage.ts Image resize for uploads 180 193 seedPhraseParser.ts Seed phrase text extraction (numbered grids, plain lists) 181 - cn.ts Tailwind class merge utility 182 - docs-registry.ts Documentation section metadata 183 - og-meta.ts Open Graph meta tag helpers 194 + sharing.ts Share dialog helpers 195 + workspaceSchemas.ts Workspace form validation 184 196 stores/ 185 197 auth.ts Auth + identity state machine (Zustand + @opake/sdk) 186 198 app.ts App-wide loading tracker 199 + tasks.ts Daemon task status display 187 200 toast.ts Toast notifications 188 201 routes/ TanStack Router file-based routing 189 202 __root.tsx Root layout (HTML shell, error boundary) 190 203 _public.tsx Public layout (nav, footer — SSR) 191 204 _public/ Public routes (landing, docs, FAQ) 192 - cabinet/ Cabinet routes (lazy-loaded, auth-guarded) 205 + cabinet/ Cabinet + workspace routes (lazy-loaded, auth-guarded) 193 206 devices/ Device + identity routes (lazy-loaded) 194 207 components/ 195 208 cabinet/ File browser, sidebar, editor, workspace UI 209 + FileView.tsx Unified cabinet + workspace file browser 210 + EditorView.tsx Shared markdown editor shell (edit / new modes) 211 + MarkdownEditor.tsx Tiptap-based editor surface 212 + MarkdownPreview.tsx Rendered markdown with mermaid support 213 + FilePreview.tsx Side-panel content preview 214 + DirectoryReadme.tsx README auto-render 215 + PanelContent.tsx File grid/list view 216 + PanelShell.tsx Panel container 217 + Sidebar.tsx Navigation sidebar 218 + TopBar.tsx Header with account switcher 219 + Breadcrumbs.tsx Path breadcrumbs 220 + (+ dialogs and smaller widgets: AddMember, CreateWorkspace, Delete, Move, 221 + NewFolder, Rename, Share, ShareManagement, Revoke, Invite, Metadata, 222 + WorkspaceMembers, WorkspaceSettings, ImageInsert, etc.) 196 223 devices/ Identity setup, seed phrase, pairing, conflict resolution 197 224 content/ MDX rendering, landing page sections 198 - PanelContent.tsx File grid/list view 199 - PanelShell.tsx Panel container 200 - Sidebar.tsx Navigation sidebar 201 - TopBar.tsx Header with account switcher 202 - FileGridCard.tsx Grid card with file icon + metadata 203 - FileListRow.tsx List row variant 204 - FilePreview.tsx File content preview 205 - MarkdownEditor.tsx In-browser markdown editing 206 - SearchResults.tsx Search results panel 207 - types.ts Discriminated union types for cabinet state 208 - (+ dialogs: AddMember, CreateWorkspace, Delete, Move, NewFolder, Rename, Share, WorkspaceMembers, WorkspaceSettings, etc.) 209 - wasm/opake-wasm/ WASM build of opake-core (via wasm-pack) 210 - workers/ 211 - opake.worker.ts Single worker composing all API modules (Comlink) 212 - daemon.ts Background daemon (session refresh, cleanup tasks) 213 - context.ts Worker context management 214 - api/ 215 - cabinet.ts Cabinet file operations 216 - identity.ts Keypairs, seed phrases, DPoP, DID resolution 217 - workspace.ts Workspace operations 225 + 226 + WASM lives in `packages/opake-sdk/wasm/` — built by `just wasm` and imported 227 + via `@opake/sdk`. No web-local worker layer: all file/identity operations go 228 + through `@opake/sdk` and `@opake/react` hooks on the main thread. 218 229 219 230 indexer/ Elixir/Phoenix indexer + REST API (replaces Rust indexer) 220 231 lib/
+2 -2
docs/FLOWS.md
··· 49 49 50 50 **Watcher teardown** 51 51 52 - `stopSseConsumer` → `WorkspaceKeeper::uninstall_all` (clears entries, watchers, resets `loaded`). `detachWatcher` (store-level) closes the JS watcher handle and clears the bootstrap promise without touching store state, so a remount reinstalls a fresh watcher without a flash-to-empty. 52 + `wipeState` → `WorkspaceKeeper::uninstall_all` (clears entries, watchers, resets `loaded`). `stopSseConsumer` only flips the consumer's cancellation flag; the keeper drain lives on `wipeState` so callers that need to stop streaming without losing decrypted state (e.g. temporary network pause) can do so without forcing a fresh re-bootstrap. 53 53 54 54 See `WorkspaceKeeper` in `crates/opake-core/src/workspace_keeper/` and `apply_keyring_to_workspace_keeper` in `crates/opake-wasm/src/sse_wasm.rs`. 55 55 ··· 76 76 77 77 **Watcher teardown** 78 78 79 - `stopSseConsumer` → `InboxKeeper::uninstall_all` (clears entries, watchers, resets `loaded`). 79 + `wipeState` → `InboxKeeper::uninstall_all` (clears entries, watchers, resets `loaded`). See the `WorkspaceKeeper` section above for the reason `stopSseConsumer` doesn't drain the keepers itself. 80 80 81 81 See `InboxKeeper` in `crates/opake-core/src/inbox_keeper/` and `apply_grant_to_inbox_keeper` in `crates/opake-wasm/src/sse_wasm.rs`.
+2 -1
packages/opake-daemon/src/scheduler.ts
··· 47 47 * onSessionExpired: () => redirectToLogin(), 48 48 * }); 49 49 * 50 - * // Later: 50 + * // Later (shutdown): 51 51 * daemon.stop(); 52 52 * opake.stopSseConsumer(); 53 + * opake.wipeState(); // drops decrypted keepers — only on logout/session switch 53 54 * ``` 54 55 */ 55 56 export function startDaemon(
+2 -2
packages/opake-sdk/src/file-manager.ts
··· 209 209 /** 210 210 * Delete a document. 211 211 * 212 - * Removes the document record and its blob from the PDS. If a parent 213 - * directory URI is provided, also removes the entry from that directory. 212 + * Removes the document record and its blob from the PDS and atomically 213 + * removes the entry from its parent directory. 214 214 * 215 215 * @param documentUri - AT URI of the document to delete. 216 216 * @param parentDirectoryUri - Directory containing the document. Required: