File size: 2,953 Bytes
3e05655
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
export type Result<T> = { ok: true; value: T } | { ok: false; error: string }

export interface Init {
  basePath: string
  frecencyDbPath?: string
  historyDbPath?: string
  useUnsafeNoLock?: boolean
  disableMmapCache?: boolean
  disableContentIndexing?: boolean
  disableWatch?: boolean
  aiMode?: boolean
  logFilePath?: string
  logLevel?: "trace" | "debug" | "info" | "warn" | "error"
  enableFsRootScanning?: boolean
  enableHomeDirScanning?: boolean
}

export interface File {
  relativePath: string
  fileName: string
  modified: number
}

export interface Directory {
  relativePath: string
  dirName: string
  maxAccessFrecency: number
}

export type Mixed = { type: "file"; item: File } | { type: "directory"; item: Directory }

export interface Search {
  items: File[]
  scores: Array<{ total: number }>
  totalMatched: number
  totalFiles: number
}

export interface DirSearch {
  items: Directory[]
  scores: Array<{ total: number }>
  totalMatched: number
  totalDirs: number
}

export interface MixedSearch {
  items: Mixed[]
  scores: Array<{ total: number }>
  totalMatched: number
  totalFiles: number
  totalDirs: number
}

export type Cursor = null

export interface Hit {
  relativePath: string
  fileName: string
  lineNumber: number
  byteOffset: number
  lineContent: string
  matchRanges: [number, number][]
  contextBefore?: string[]
  contextAfter?: string[]
}

export interface Grep {
  items: Hit[]
  totalMatched: number
  totalFilesSearched: number
  totalFiles: number
  filteredFileCount: number
  nextCursor: Cursor
  regexFallbackError?: string
}

export interface Picker {
  destroy(): void
  isScanning(): boolean
  waitForScan(timeoutMs?: number): Promise<Result<boolean>>
  refreshGitStatus(): Result<number>
  fileSearch(
    query: string,
    opts?: {
      currentFile?: string
      pageIndex?: number
      pageSize?: number
    },
  ): Result<Search>
  glob(
    pattern: string,
    opts?: {
      currentFile?: string
      pageIndex?: number
      pageSize?: number
    },
  ): Result<Search>
  directorySearch(
    query: string,
    opts?: {
      currentFile?: string
      pageIndex?: number
      pageSize?: number
    },
  ): Result<DirSearch>
  mixedSearch(
    query: string,
    opts?: {
      currentFile?: string
      pageIndex?: number
      pageSize?: number
    },
  ): Result<MixedSearch>
  grep(
    query: string,
    opts?: {
      mode?: "plain" | "regex" | "fuzzy"
      maxMatchesPerFile?: number
      timeBudgetMs?: number
      beforeContext?: number
      afterContext?: number
      cursor?: Cursor
      pageSize?: number
    },
  ): Result<Grep>
  trackQuery(query: string, file: string): Result<boolean>
  getHistoricalQuery(offset: number): Result<string | null>
}

export function available() {
  return false
}

export function create(_opts: Init): Result<Picker> {
  return { ok: false, error: "fff unavailable on node runtime" }
}

export * as Fff from "./fff.node"