fix(vfs): add sourceId+verbType optimization to fix readdir()
CRITICAL VFS BUG FIX - Root Cause Analysis:
The issue was that baseStorage.getVerbs() had optimizations for:
- sourceId only
- targetId only
- verbType only
But VFS PathResolver.getChildren() queries with BOTH sourceId AND verbType:
getRelations({ from: dirId, type: VerbType.Contains })
This combination wasn't optimized, so it fell through to the
getVerbsWithPagination() path, which MemoryStorage doesn't implement,
causing it to return empty results.
Fix: Added optimization for sourceId + verbType combination
- Uses O(1) graph index lookup for sourceId
- Filters results by verbType in O(n)
- Enables VFS readdir() to work correctly
This was the real bug preventing Workshop team from seeing their
567 markdown files in vfs.readdir('/').
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
38c41e012e
commit
e66a8a2c69
1 changed files with 40 additions and 0 deletions
|
|
@ -631,6 +631,46 @@ export abstract class BaseStorage extends BaseStorageAdapter {
|
|||
|
||||
// Optimize for common filter cases to avoid loading all verbs
|
||||
if (options?.filter) {
|
||||
// CRITICAL VFS FIX: If filtering by sourceId + verbType (most common VFS pattern!)
|
||||
// This is the query PathResolver.getChildren() uses: getRelations({ from: dirId, type: VerbType.Contains })
|
||||
if (
|
||||
options.filter.sourceId &&
|
||||
options.filter.verbType &&
|
||||
!options.filter.targetId &&
|
||||
!options.filter.service &&
|
||||
!options.filter.metadata
|
||||
) {
|
||||
const sourceId = Array.isArray(options.filter.sourceId)
|
||||
? options.filter.sourceId[0]
|
||||
: options.filter.sourceId
|
||||
|
||||
const verbType = Array.isArray(options.filter.verbType)
|
||||
? options.filter.verbType[0]
|
||||
: options.filter.verbType
|
||||
|
||||
// Get verbs by source, then filter by type (O(1) graph lookup + O(n) type filter)
|
||||
const verbsBySource = await this.getVerbsBySource_internal(sourceId)
|
||||
const filteredVerbs = verbsBySource.filter(v => v.verb === verbType)
|
||||
|
||||
// Apply pagination
|
||||
const paginatedVerbs = filteredVerbs.slice(offset, offset + limit)
|
||||
const hasMore = offset + limit < filteredVerbs.length
|
||||
|
||||
// Set next cursor if there are more items
|
||||
let nextCursor: string | undefined = undefined
|
||||
if (hasMore && paginatedVerbs.length > 0) {
|
||||
const lastItem = paginatedVerbs[paginatedVerbs.length - 1]
|
||||
nextCursor = lastItem.id
|
||||
}
|
||||
|
||||
return {
|
||||
items: paginatedVerbs,
|
||||
totalCount: filteredVerbs.length,
|
||||
hasMore,
|
||||
nextCursor
|
||||
}
|
||||
}
|
||||
|
||||
// If filtering by sourceId only, use the optimized method
|
||||
if (
|
||||
options.filter.sourceId &&
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue