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
|
// Optimize for common filter cases to avoid loading all verbs
|
||||||
if (options?.filter) {
|
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 filtering by sourceId only, use the optimized method
|
||||||
if (
|
if (
|
||||||
options.filter.sourceId &&
|
options.filter.sourceId &&
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue