metro-file-map 0.76.0 → 0.76.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metro-file-map",
3
- "version": "0.76.0",
3
+ "version": "0.76.2",
4
4
  "description": "[Experimental] - 🚇 File crawling, watching and mapping for Metro",
5
5
  "main": "src/index.js",
6
6
  "repository": {
@@ -13,17 +13,16 @@
13
13
  },
14
14
  "license": "MIT",
15
15
  "dependencies": {
16
- "abort-controller": "^3.0.0",
17
16
  "anymatch": "^3.0.3",
18
17
  "debug": "^2.2.0",
19
18
  "fb-watchman": "^2.0.0",
20
19
  "graceful-fs": "^4.2.4",
21
20
  "invariant": "^2.2.4",
22
21
  "jest-regex-util": "^27.0.6",
23
- "jest-serializer": "^27.0.6",
24
22
  "jest-util": "^27.2.0",
25
23
  "jest-worker": "^27.2.0",
26
24
  "micromatch": "^4.0.4",
25
+ "node-abort-controller": "^3.1.1",
27
26
  "nullthrows": "^1.1.1",
28
27
  "walker": "^1.0.7"
29
28
  },
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall react_native
9
+ */
10
+
11
+ import type {
12
+ HTypeValue,
13
+ IModuleMap,
14
+ Path,
15
+ ReadOnlyRawModuleMap,
16
+ } from './flow-types';
17
+
18
+ export default class ModuleMap implements IModuleMap {
19
+ getModule(
20
+ name: string,
21
+ platform?: string | null,
22
+ supportsNativePlatform?: boolean | null,
23
+ type?: HTypeValue | null,
24
+ ): Path | null;
25
+ getPackage(
26
+ name: string,
27
+ platform: string | null,
28
+ _supportsNativePlatform?: boolean | null,
29
+ ): Path | null;
30
+ getMockModule(name: string): Path | null;
31
+ getRawModuleMap(): ReadOnlyRawModuleMap;
32
+ static create(rootDir: Path): ModuleMap;
33
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall react_native
9
+ */
10
+
11
+ export type HealthCheckResult =
12
+ | {type: 'error'; timeout: number; error: Error; watcher: string | null}
13
+ | {
14
+ type: 'success';
15
+ timeout: number;
16
+ timeElapsed: number;
17
+ watcher: string | null;
18
+ }
19
+ | {
20
+ type: 'timeout';
21
+ timeout: number;
22
+ watcher: string | null;
23
+ pauseReason: string | null;
24
+ };
package/src/Watcher.js CHANGED
@@ -92,6 +92,7 @@ class Watcher extends _events.default {
92
92
  path.basename(filePath).startsWith(this._options.healthCheckFilePrefix);
93
93
  const crawl = options.useWatchman ? _watchman.default : _node.default;
94
94
  let crawler = crawl === _watchman.default ? "watchman" : "node";
95
+ options.abortSignal.throwIfAborted();
95
96
  const crawlerOptions = {
96
97
  abortSignal: options.abortSignal,
97
98
  computeSha1: options.computeSha1,
@@ -286,6 +287,7 @@ class Watcher extends _events.default {
286
287
  this._pendingHealthChecks.delete(basename);
287
288
  // Chain a deletion to the creation promise (which may not have even settled yet!),
288
289
  // don't await it, and swallow errors. This is just best-effort cleanup.
290
+ // $FlowFixMe[unused-promise]
289
291
  creationPromise.then(() =>
290
292
  fs.promises.unlink(healthCheckPath).catch(() => {})
291
293
  );
@@ -18,6 +18,7 @@ import type {
18
18
  WatchmanClocks,
19
19
  } from './flow-types';
20
20
  import type {WatcherOptions as WatcherBackendOptions} from './watchers/common';
21
+ import type {AbortSignal} from 'node-abort-controller';
21
22
 
22
23
  import watchmanCrawl from './crawlers/watchman';
23
24
  import nodeCrawl from './crawlers/node';
@@ -96,6 +97,9 @@ export class Watcher extends EventEmitter {
96
97
  path.basename(filePath).startsWith(this._options.healthCheckFilePrefix);
97
98
  const crawl = options.useWatchman ? watchmanCrawl : nodeCrawl;
98
99
  let crawler = crawl === watchmanCrawl ? 'watchman' : 'node';
100
+
101
+ options.abortSignal.throwIfAborted();
102
+
99
103
  const crawlerOptions: CrawlerOptions = {
100
104
  abortSignal: options.abortSignal,
101
105
  computeSha1: options.computeSha1,
@@ -314,6 +318,7 @@ export class Watcher extends EventEmitter {
314
318
  this._pendingHealthChecks.delete(basename);
315
319
  // Chain a deletion to the creation promise (which may not have even settled yet!),
316
320
  // don't await it, and swallow errors. This is just best-effort cleanup.
321
+ // $FlowFixMe[unused-promise]
317
322
  creationPromise.then(() =>
318
323
  fs.promises.unlink(healthCheckPath).catch(() => {}),
319
324
  );
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall react_native
9
+ */
10
+
11
+ import type {
12
+ BuildParameters,
13
+ CacheData,
14
+ CacheManager,
15
+ FileData,
16
+ } from '../flow-types';
17
+
18
+ export interface DiskCacheConfig {
19
+ buildParameters: BuildParameters;
20
+ cacheFilePrefix?: string | null;
21
+ cacheDirectory?: string | null;
22
+ }
23
+
24
+ export class DiskCacheManager implements CacheManager {
25
+ constructor(options: DiskCacheConfig);
26
+ static getCacheFilePath(
27
+ buildParameters: BuildParameters,
28
+ cacheFilePrefix?: string | null,
29
+ cacheDirectory?: string | null,
30
+ ): string;
31
+ getCacheFilePath(): string;
32
+ read(): Promise<CacheData | null>;
33
+ write(
34
+ dataSnapshot: CacheData,
35
+ {changed, removed}: Readonly<{changed: FileData; removed: FileData}>,
36
+ ): Promise<void>;
37
+ }
@@ -185,14 +185,16 @@ module.exports = async function nodeCrawl(options) {
185
185
  includeSymlinks,
186
186
  perfLogger,
187
187
  roots,
188
+ abortSignal,
188
189
  } = options;
190
+ abortSignal?.throwIfAborted();
189
191
  perfLogger?.point("nodeCrawl_start");
190
192
  const useNativeFind =
191
193
  !forceNodeFilesystemAPI &&
192
194
  (0, _os.platform)() !== "win32" &&
193
195
  (await (0, _hasNativeFindSupport.default)());
194
196
  debug("Using system find: %s", useNativeFind);
195
- return new Promise((resolve) => {
197
+ return new Promise((resolve, reject) => {
196
198
  const callback = (list) => {
197
199
  const changedFiles = new Map();
198
200
  const removedFiles = new Map(previousState.files);
@@ -218,6 +220,12 @@ module.exports = async function nodeCrawl(options) {
218
220
  }
219
221
  }
220
222
  perfLogger?.point("nodeCrawl_end");
223
+ try {
224
+ // TODO: Use AbortSignal.reason directly when Flow supports it
225
+ abortSignal?.throwIfAborted();
226
+ } catch (e) {
227
+ reject(e);
228
+ }
221
229
  resolve({
222
230
  changedFiles,
223
231
  removedFiles,
@@ -175,7 +175,11 @@ module.exports = async function nodeCrawl(options: CrawlerOptions): Promise<{
175
175
  includeSymlinks,
176
176
  perfLogger,
177
177
  roots,
178
+ abortSignal,
178
179
  } = options;
180
+
181
+ abortSignal?.throwIfAborted();
182
+
179
183
  perfLogger?.point('nodeCrawl_start');
180
184
  const useNativeFind =
181
185
  !forceNodeFilesystemAPI &&
@@ -184,7 +188,7 @@ module.exports = async function nodeCrawl(options: CrawlerOptions): Promise<{
184
188
 
185
189
  debug('Using system find: %s', useNativeFind);
186
190
 
187
- return new Promise(resolve => {
191
+ return new Promise((resolve, reject) => {
188
192
  const callback = (list: Result) => {
189
193
  const changedFiles = new Map<Path, FileMetaData>();
190
194
  const removedFiles = new Map(previousState.files);
@@ -208,6 +212,13 @@ module.exports = async function nodeCrawl(options: CrawlerOptions): Promise<{
208
212
  }
209
213
 
210
214
  perfLogger?.point('nodeCrawl_end');
215
+
216
+ try {
217
+ // TODO: Use AbortSignal.reason directly when Flow supports it
218
+ abortSignal?.throwIfAborted();
219
+ } catch (e) {
220
+ reject(e);
221
+ }
211
222
  resolve({
212
223
  changedFiles,
213
224
  removedFiles,
@@ -85,10 +85,11 @@ module.exports = async function watchmanCrawl({
85
85
  rootDir,
86
86
  roots,
87
87
  }) {
88
- perfLogger?.point("watchmanCrawl_start");
89
- const newClocks = new Map();
88
+ abortSignal?.throwIfAborted();
90
89
  const client = new watchman.Client();
91
90
  abortSignal?.addEventListener("abort", () => client.end());
91
+ perfLogger?.point("watchmanCrawl_start");
92
+ const newClocks = new Map();
92
93
  let clientError;
93
94
  client.on("error", (error) => {
94
95
  clientError = makeWatchmanError(error);
@@ -274,6 +275,7 @@ module.exports = async function watchmanCrawl({
274
275
  });
275
276
  }
276
277
  perfLogger?.point("watchmanCrawl_end");
278
+ abortSignal?.throwIfAborted();
277
279
  throw (
278
280
  queryError ?? clientError ?? new Error("Watchman file results missing")
279
281
  );
@@ -356,6 +358,7 @@ module.exports = async function watchmanCrawl({
356
358
  }
357
359
  perfLogger?.point("watchmanCrawl/processResults_end");
358
360
  perfLogger?.point("watchmanCrawl_end");
361
+ abortSignal?.throwIfAborted();
359
362
  return {
360
363
  changedFiles,
361
364
  removedFiles,
@@ -62,13 +62,15 @@ module.exports = async function watchmanCrawl({
62
62
  removedFiles: FileData,
63
63
  clocks: WatchmanClocks,
64
64
  }> {
65
- perfLogger?.point('watchmanCrawl_start');
66
-
67
- const newClocks = new Map<Path, WatchmanClockSpec>();
65
+ abortSignal?.throwIfAborted();
68
66
 
69
67
  const client = new watchman.Client();
70
68
  abortSignal?.addEventListener('abort', () => client.end());
71
69
 
70
+ perfLogger?.point('watchmanCrawl_start');
71
+
72
+ const newClocks = new Map<Path, WatchmanClockSpec>();
73
+
72
74
  let clientError;
73
75
  client.on('error', error => {
74
76
  clientError = makeWatchmanError(error);
@@ -280,6 +282,7 @@ module.exports = async function watchmanCrawl({
280
282
  });
281
283
  }
282
284
  perfLogger?.point('watchmanCrawl_end');
285
+ abortSignal?.throwIfAborted();
283
286
  throw (
284
287
  queryError ?? clientError ?? new Error('Watchman file results missing')
285
288
  );
@@ -378,6 +381,7 @@ module.exports = async function watchmanCrawl({
378
381
 
379
382
  perfLogger?.point('watchmanCrawl/processResults_end');
380
383
  perfLogger?.point('watchmanCrawl_end');
384
+ abortSignal?.throwIfAborted();
381
385
  return {
382
386
  changedFiles,
383
387
  removedFiles,
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall react_native
9
+ */
10
+
11
+ import type ModuleMap from './ModuleMap';
12
+ import type {PerfLoggerFactory, RootPerfLogger, PerfLogger} from 'metro-config';
13
+ import type {AbortSignal} from 'node-abort-controller';
14
+
15
+ export type {PerfLoggerFactory, PerfLogger};
16
+
17
+ /**
18
+ * These inputs affect the internal data collected for a given filesystem
19
+ * state, and changes may invalidate a cache.
20
+ */
21
+ export type BuildParameters = Readonly<{
22
+ computeDependencies: boolean;
23
+ computeSha1: boolean;
24
+ enableSymlinks: boolean;
25
+ extensions: ReadonlyArray<string>;
26
+ forceNodeFilesystemAPI: boolean;
27
+ ignorePattern: RegExp;
28
+ mocksPattern: RegExp | null;
29
+ platforms: ReadonlyArray<string>;
30
+ retainAllFiles: boolean;
31
+ rootDir: string;
32
+ roots: ReadonlyArray<string>;
33
+ skipPackageJson: boolean;
34
+ dependencyExtractor: string | null;
35
+ hasteImplModulePath: string | null;
36
+ cacheBreaker: string;
37
+ }>;
38
+
39
+ export interface BuildResult {
40
+ fileSystem: FileSystem;
41
+ hasteModuleMap: ModuleMap;
42
+ }
43
+
44
+ export interface CacheData {
45
+ readonly clocks: WatchmanClocks;
46
+ readonly map: RawModuleMap['map'];
47
+ readonly mocks: RawModuleMap['mocks'];
48
+ readonly duplicates: RawModuleMap['duplicates'];
49
+ readonly files: FileData;
50
+ }
51
+
52
+ export interface CacheManager {
53
+ read(): Promise<CacheData | null>;
54
+ write(
55
+ dataSnapshot: CacheData,
56
+ delta: Readonly<{changed: FileData; removed: FileData}>,
57
+ ): Promise<void>;
58
+ }
59
+
60
+ export type CacheManagerFactory = (
61
+ buildParameters: BuildParameters,
62
+ ) => CacheManager;
63
+
64
+ export interface ChangeEvent {
65
+ logger: RootPerfLogger | null;
66
+ eventsQueue: EventsQueue;
67
+ }
68
+
69
+ export interface ChangeEventMetadata {
70
+ /** Epoch ms */
71
+ modifiedTime: number | null;
72
+ /** Bytes */
73
+ size: number | null;
74
+ /** Regular file / Directory / Symlink */
75
+ type: 'f' | 'd' | 'l';
76
+ }
77
+
78
+ export type Console = typeof global.console;
79
+
80
+ export interface CrawlerOptions {
81
+ abortSignal: AbortSignal | null;
82
+ computeSha1: boolean;
83
+ extensions: ReadonlyArray<string>;
84
+ forceNodeFilesystemAPI: boolean;
85
+ ignore: IgnoreMatcher;
86
+ includeSymlinks: boolean;
87
+ perfLogger?: PerfLogger | null;
88
+ previousState: Readonly<{
89
+ clocks: ReadonlyMap<Path, WatchmanClockSpec>;
90
+ files: ReadonlyMap<Path, FileMetaData>;
91
+ }>;
92
+ rootDir: string;
93
+ roots: ReadonlyArray<string>;
94
+ onStatus: (status: WatcherStatus) => void;
95
+ }
96
+
97
+ export type WatcherStatus =
98
+ | {
99
+ type: 'watchman_slow_command';
100
+ timeElapsed: number;
101
+ command: 'watch-project' | 'query';
102
+ }
103
+ | {
104
+ type: 'watchman_slow_command_complete';
105
+ timeElapsed: number;
106
+ command: 'watch-project' | 'query';
107
+ }
108
+ | {
109
+ type: 'watchman_warning';
110
+ warning: unknown;
111
+ command: 'watch-project' | 'query';
112
+ };
113
+
114
+ export type DuplicatesSet = Map<string, /* type */ number>;
115
+ export type DuplicatesIndex = Map<string, Map<string, DuplicatesSet>>;
116
+
117
+ export type EventsQueue = Array<{
118
+ filePath: Path;
119
+ metadata?: ChangeEventMetadata | null;
120
+ type: string;
121
+ }>;
122
+
123
+ export interface HType {
124
+ ID: 0;
125
+ MTIME: 1;
126
+ SIZE: 2;
127
+ VISITED: 3;
128
+ DEPENDENCIES: 4;
129
+ SHA1: 5;
130
+ SYMLINK: 6;
131
+ PATH: 0;
132
+ TYPE: 1;
133
+ MODULE: 0;
134
+ PACKAGE: 1;
135
+ GENERIC_PLATFORM: 'g';
136
+ NATIVE_PLATFORM: 'native';
137
+ DEPENDENCY_DELIM: '\0';
138
+ }
139
+
140
+ type Values<T> = T[keyof T];
141
+ export type HTypeValue = Values<HType>;
142
+
143
+ export type IgnoreMatcher = (item: string) => boolean;
144
+
145
+ export type FileData = Map<Path, FileMetaData>;
146
+
147
+ export type FileMetaData = [
148
+ /* id */ string,
149
+ /* mtime */ number,
150
+ /* size */ number,
151
+ /* visited */ 0 | 1,
152
+ /* dependencies */ string,
153
+ /* sha1 */ string | null,
154
+ /* symlink */ 0 | 1 | string, // string specifies target, if known
155
+ ];
156
+
157
+ export type FileStats = Readonly<{
158
+ fileType: 'f' | 'l';
159
+ modifiedTime: number;
160
+ }>;
161
+
162
+ export interface FileSystem {
163
+ exists(file: Path): boolean;
164
+ getAllFiles(): Path[];
165
+ getDependencies(file: Path): string[] | null;
166
+ getModuleName(file: Path): string | null;
167
+ getRealPath(file: Path): string | null;
168
+ getSerializableSnapshot(): FileData;
169
+ getSha1(file: Path): string | null;
170
+
171
+ /**
172
+ * Analogous to posix lstat. If the file at `file` is a symlink, return
173
+ * information about the symlink without following it.
174
+ */
175
+ linkStats(file: Path): FileStats | null;
176
+
177
+ matchFiles(pattern: RegExp | string): Path[];
178
+
179
+ /**
180
+ * Given a search context, return a list of file paths matching the query.
181
+ * The query matches against normalized paths which start with `./`,
182
+ * for example: `a/b.js` -> `./a/b.js`
183
+ */
184
+ matchFilesWithContext(
185
+ root: Path,
186
+ context: Readonly<{
187
+ /* Should search for files recursively. */
188
+ recursive: boolean;
189
+ /* Filter relative paths against a pattern. */
190
+ filter: RegExp;
191
+ }>,
192
+ ): Path[];
193
+ }
194
+
195
+ export type Glob = string;
196
+
197
+ // tslint:disable-next-line interface-name
198
+ export interface IModuleMap {
199
+ getModule(
200
+ name: string,
201
+ platform?: string | null,
202
+ supportsNativePlatform?: boolean | null,
203
+ type?: HTypeValue | null,
204
+ ): Path | null;
205
+
206
+ getPackage(
207
+ name: string,
208
+ platform: string | null,
209
+ _supportsNativePlatform: boolean | null,
210
+ ): Path | null;
211
+
212
+ getMockModule(name: string): Path | null;
213
+
214
+ getRawModuleMap(): ReadOnlyRawModuleMap;
215
+ }
216
+
217
+ export type MockData = Map<string, Path>;
218
+ export type ModuleMapData = Map<string, ModuleMapItem>;
219
+
220
+ export interface ModuleMapItem {
221
+ [platform: string]: ModuleMetaData;
222
+ }
223
+ export type ModuleMetaData = [/* path */ string, /* type */ number];
224
+
225
+ export interface MutableFileSystem extends FileSystem {
226
+ remove(filePath: Path): void;
227
+ addOrModify(filePath: Path, fileMetadata: FileMetaData): void;
228
+ bulkAddOrModify(addedOrModifiedFiles: FileData): void;
229
+ }
230
+
231
+ export type Path = string;
232
+
233
+ export interface RawModuleMap {
234
+ rootDir: Path;
235
+ duplicates: DuplicatesIndex;
236
+ map: ModuleMapData;
237
+ mocks: MockData;
238
+ }
239
+
240
+ export type ReadOnlyRawModuleMap = Readonly<{
241
+ rootDir: Path;
242
+ duplicates: ReadonlyMap<
243
+ string,
244
+ ReadonlyMap<string, ReadonlyMap<string, number>>
245
+ >;
246
+ map: ReadonlyMap<string, ModuleMapItem>;
247
+ mocks: ReadonlyMap<string, Path>;
248
+ }>;
249
+
250
+ export type WatchmanClockSpec =
251
+ | string
252
+ | Readonly<{scm: Readonly<{'mergebase-with': string}>}>;
253
+ export type WatchmanClocks = Map<Path, WatchmanClockSpec>;
254
+
255
+ export type WorkerMessage = Readonly<{
256
+ computeDependencies: boolean;
257
+ computeSha1: boolean;
258
+ dependencyExtractor?: string | null;
259
+ enableHastePackages: boolean;
260
+ readLink: boolean;
261
+ rootDir: string;
262
+ filePath: string;
263
+ hasteImplModulePath?: string | null;
264
+ }>;
265
+
266
+ export type WorkerMetadata = Readonly<{
267
+ dependencies?: ReadonlyArray<string>;
268
+ id?: string | null;
269
+ module?: ModuleMetaData | null;
270
+ sha1?: string | null;
271
+ symlinkTarget?: string | null;
272
+ }>;
@@ -13,6 +13,7 @@
13
13
 
14
14
  import type ModuleMap from './ModuleMap';
15
15
  import type {PerfLoggerFactory, RootPerfLogger, PerfLogger} from 'metro-config';
16
+ import type {AbortSignal} from 'node-abort-controller';
16
17
 
17
18
  export type {PerfLoggerFactory, PerfLogger};
18
19
 
package/src/index.d.ts ADDED
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall react_native
9
+ */
10
+
11
+ import type {
12
+ BuildParameters,
13
+ BuildResult,
14
+ CacheData,
15
+ CacheManagerFactory,
16
+ ChangeEventMetadata,
17
+ Console,
18
+ FileData,
19
+ FileSystem,
20
+ ModuleMapData,
21
+ ModuleMapItem,
22
+ PerfLoggerFactory,
23
+ } from './flow-types';
24
+ import type {EventEmitter} from 'events';
25
+
26
+ export type {
27
+ BuildParameters,
28
+ CacheData,
29
+ ChangeEventMetadata,
30
+ FileData,
31
+ FileSystem,
32
+ HasteMap,
33
+ ModuleMapData,
34
+ ModuleMapItem,
35
+ };
36
+
37
+ export type InputOptions = Readonly<{
38
+ computeDependencies?: boolean | null;
39
+ computeSha1?: boolean | null;
40
+ enableSymlinks?: boolean | null;
41
+ extensions: ReadonlyArray<string>;
42
+ forceNodeFilesystemAPI?: boolean | null;
43
+ ignorePattern?: RegExp | null;
44
+ mocksPattern?: string | null;
45
+ platforms: ReadonlyArray<string>;
46
+ retainAllFiles: boolean;
47
+ rootDir: string;
48
+ roots: ReadonlyArray<string>;
49
+ skipPackageJson?: boolean | null;
50
+
51
+ /** Module paths that should export a 'getCacheKey' method */
52
+ dependencyExtractor?: string | null;
53
+ hasteImplModulePath?: string | null;
54
+
55
+ perfLoggerFactory?: PerfLoggerFactory | null;
56
+ resetCache?: boolean | null;
57
+ maxWorkers: number;
58
+ throwOnModuleCollision?: boolean | null;
59
+ useWatchman?: boolean | null;
60
+ watchmanDeferStates?: ReadonlyArray<string>;
61
+ watch?: boolean | null;
62
+ console?: Console;
63
+ cacheManagerFactory?: CacheManagerFactory | null;
64
+
65
+ healthCheck: HealthCheckOptions;
66
+ }>;
67
+
68
+ type HealthCheckOptions = Readonly<{
69
+ enabled: boolean;
70
+ interval: number;
71
+ timeout: number;
72
+ filePrefix: string;
73
+ }>;
74
+
75
+ export {default as ModuleMap} from './ModuleMap';
76
+ export {DiskCacheManager} from './cache/DiskCacheManager';
77
+ export {DuplicateHasteCandidatesError} from './lib/DuplicateHasteCandidatesError';
78
+ export type {IModuleMap} from './flow-types';
79
+ export type {HealthCheckResult} from './Watcher';
80
+ export type {
81
+ CacheManager,
82
+ CacheManagerFactory,
83
+ ChangeEvent,
84
+ WatcherStatus,
85
+ } from './flow-types';
86
+
87
+ export default class HasteMap extends EventEmitter {
88
+ static create(options: InputOptions): HasteMap;
89
+ constructor(options: InputOptions);
90
+ build(): Promise<BuildResult>;
91
+ read(): Promise<CacheData | null>;
92
+ }
93
+
94
+ export class DuplicateError extends Error {}