File system crawling, watching and mapping library designed for Metro bundler ecosystem
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Metro File Map is an experimental file system crawling, watching and mapping library designed specifically for the Metro bundler ecosystem. Originally forked from jest-haste-map, it provides comprehensive file system operations including directory traversal, file change monitoring, and mapping capabilities essential for JavaScript bundling workflows.
npm install metro-file-mapimport FileMap, { DiskCacheManager, HastePlugin } from "metro-file-map";For CommonJS:
const FileMap = require("metro-file-map").default;
const { DiskCacheManager, HastePlugin } = require("metro-file-map");import FileMap from "metro-file-map";
const fileMap = new FileMap({
extensions: ['.js', '.json'],
platforms: ['ios', 'android', 'native'],
retainAllFiles: false,
rootDir: '/path/to/project',
roots: ['/path/to/project/src'],
maxWorkers: 4,
healthCheck: {
enabled: false,
interval: 30000,
timeout: 5000,
filePrefix: 'metro-file-map-health-check'
}
});
// Build the file map
const result = await fileMap.build();
const { fileSystem, hasteMap } = result;
// Query the file system
const allFiles = fileSystem.getAllFiles();
const moduleName = hasteMap.getModule('MyComponent');
// Clean up
await fileMap.end();Metro File Map is built around several key components:
Main FileMap class for orchestrating file system operations, watching, and caching.
class FileMap extends EventEmitter {
static create(options: InputOptions): FileMap;
constructor(options: InputOptions);
build(): Promise<BuildResult>;
read(): Promise<CacheData | null>;
end(): Promise<void>;
}
interface BuildResult {
fileSystem: FileSystem,
hasteMap: HasteMap,
mockMap: MockMap | null
}Virtual file system providing querying, lookup, and metadata operations.
interface FileSystem {
exists(file: string): boolean;
getAllFiles(): Array<string>;
getDependencies(file: string): Array<string> | null;
getModuleName(file: string): string | null;
getSha1(file: string): string | null;
matchFiles(opts: MatchFilesOptions): Iterable<string>;
lookup(mixedPath: string): LookupResult;
}Haste module resolution and conflict detection system.
interface HasteMap {
getModule(name: string, platform?: string, supportsNativePlatform?: boolean, type?: number): string | null;
getPackage(name: string, platform?: string, supportsNativePlatform?: boolean): string | null;
computeConflicts(): Array<HasteConflict>;
}Pluggable caching system with disk-based implementation for persistent storage.
interface CacheManager {
read(): Promise<CacheData | null>;
write(getSnapshot: () => CacheData, opts: CacheManagerWriteOptions): Promise<void>;
end(): Promise<void>;
}
class DiskCacheManager implements CacheManager {
constructor(options: CacheManagerFactoryOptions, config: DiskCacheConfig);
static getCacheFilePath(buildParameters: BuildParameters, cacheFilePrefix?: string, cacheDirectory?: string): string;
}Extensible plugin system for Haste modules, mocks, and custom file processing.
interface FileMapPlugin<SerializableState> {
+name: string;
initialize(initOptions: FileMapPluginInitOptions<SerializableState>): Promise<void>;
assertValid(): void;
bulkUpdate(delta: FileMapDelta): Promise<void>;
getSerializableSnapshot(): SerializableState;
onRemovedFile(relativeFilePath: string, fileMetadata: FileMetadata): void;
onNewOrModifiedFile(relativeFilePath: string, fileMetadata: FileMetadata): void;
getCacheKey(): string;
}Specialized error classes for Haste conflicts and duplicate candidates.
class HasteConflictsError extends Error {
constructor(conflicts: Array<HasteConflict>);
getDetailedMessage(pathsRelativeToRoot?: string): string;
}
class DuplicateHasteCandidatesError extends Error {
constructor(name: string, platform: string, supportsNativePlatform: boolean, duplicatesSet: DuplicatesSet);
}interface InputOptions {
// Required
extensions: ReadonlyArray<string>;
platforms: ReadonlyArray<string>;
retainAllFiles: boolean;
rootDir: string;
roots: ReadonlyArray<string>;
maxWorkers: number;
healthCheck: HealthCheckOptions;
// Optional
computeDependencies?: boolean;
computeSha1?: boolean;
enableSymlinks?: boolean;
forceNodeFilesystemAPI?: boolean;
ignorePattern?: RegExp;
mocksPattern?: string;
skipPackageJson?: boolean;
dependencyExtractor?: string;
hasteImplModulePath?: string;
perfLoggerFactory?: PerfLoggerFactory;
resetCache?: boolean;
throwOnModuleCollision?: boolean;
useWatchman?: boolean;
watch?: boolean;
watchmanDeferStates?: ReadonlyArray<string>;
console?: Console;
cacheManagerFactory?: CacheManagerFactory;
enableHastePackages?: boolean;
enableWorkerThreads?: boolean;
maxFilesPerWorker?: number;
}
interface HealthCheckOptions {
enabled: boolean;
interval: number;
timeout: number;
filePrefix: string;
}
interface ChangeEvent {
logger: RootPerfLogger | null;
eventsQueue: EventsQueue;
}
interface ChangeEventMetadata {
modifiedTime: number | null;
size: number | null;
type: 'f' | 'd' | 'l'; // File, Directory, Link
}
type FileMetadata = [
string, // id
number, // mtime
number, // size
0 | 1, // visited
string, // dependencies
string, // sha1
0 | 1 | string // symlink (0=no, 1=yes, string=target)
];
interface HasteConflict {
id: string;
platform: string | null;
absolutePaths: Array<string>;
type: 'duplicate' | 'shadowing';
}