From ecdaea8de128187c905e169323f1a6392c0076d4 Mon Sep 17 00:00:00 2001 From: ForAeons Date: Sat, 10 Aug 2024 21:40:35 +0800 Subject: [PATCH 1/2] refactor(typescript): packages/rspack/src/node/NodeWatchFileSystem --- packages/rspack/etc/api.md | 72 ++- .../rspack/src/node/NodeWatchFileSystem.ts | 23 +- packages/rspack/src/util/fs.ts | 413 +++++++++++++++++- 3 files changed, 430 insertions(+), 78 deletions(-) diff --git a/packages/rspack/etc/api.md b/packages/rspack/etc/api.md index b3880c90368..8044810d951 100644 --- a/packages/rspack/etc/api.md +++ b/packages/rspack/etc/api.md @@ -4768,58 +4768,36 @@ const infrastructureLogging: z.ZodObject<{ }>; // @public (undocumented) -interface IStats { - // (undocumented) - atime: Date; - // (undocumented) - atimeMs: number | bigint; - // (undocumented) - birthtime: Date; - // (undocumented) - birthtimeMs: number | bigint; - // (undocumented) - blksize: number | bigint; - // (undocumented) - blocks: number | bigint; - // (undocumented) - ctime: Date; - // (undocumented) - ctimeMs: number | bigint; - // (undocumented) - dev: number | bigint; - // (undocumented) - gid: number | bigint; - // (undocumented) - ino: number | bigint; - // (undocumented) +type IStats = IStatsBase; + +// @public (undocumented) +type IStatsBase = { + isFile: () => boolean; + isDirectory: () => boolean; isBlockDevice: () => boolean; - // (undocumented) isCharacterDevice: () => boolean; - // (undocumented) - isDirectory: () => boolean; - // (undocumented) + isSymbolicLink: () => boolean; isFIFO: () => boolean; - // (undocumented) - isFile: () => boolean; - // (undocumented) isSocket: () => boolean; - // (undocumented) - isSymbolicLink: () => boolean; - // (undocumented) - mode: number | bigint; - // (undocumented) + dev: T; + ino: T; + mode: T; + nlink: T; + uid: T; + gid: T; + rdev: T; + size: T; + blksize: T; + blocks: T; + atimeMs: T; + mtimeMs: T; + ctimeMs: T; + birthtimeMs: T; + atime: Date; mtime: Date; - // (undocumented) - mtimeMs: number | bigint; - // (undocumented) - nlink: number | bigint; - // (undocumented) - rdev: number | bigint; - // (undocumented) - size: number | bigint; - // (undocumented) - uid: number | bigint; -} + ctime: Date; + birthtime: Date; +}; // @public (undocumented) class ItemCacheFacade implements BaseCache { diff --git a/packages/rspack/src/node/NodeWatchFileSystem.ts b/packages/rspack/src/node/NodeWatchFileSystem.ts index c78273a3f2e..a31ab687abc 100644 --- a/packages/rspack/src/node/NodeWatchFileSystem.ts +++ b/packages/rspack/src/node/NodeWatchFileSystem.ts @@ -11,14 +11,19 @@ import util from "node:util"; import Watchpack from "watchpack"; -import type { FileSystemInfoEntry, WatchFileSystem, Watcher } from "../util/fs"; +import type { + FileSystemInfoEntry, + InputFileSystem, + WatchFileSystem, + Watcher +} from "../util/fs"; export default class NodeWatchFileSystem implements WatchFileSystem { - inputFileSystem: any; + inputFileSystem: InputFileSystem; watcherOptions: Watchpack.WatchOptions; watcher: Watchpack; - constructor(inputFileSystem: any) { + constructor(inputFileSystem: InputFileSystem) { this.inputFileSystem = inputFileSystem; this.watcherOptions = { aggregateTimeout: 0 @@ -87,10 +92,10 @@ export default class NodeWatchFileSystem implements WatchFileSystem { if (this.inputFileSystem?.purge) { const fs = this.inputFileSystem; for (const item of changes) { - fs.purge(item); + fs.purge?.(item); } for (const item of removals) { - fs.purge(item); + fs.purge?.(item); } } const { fileTimeInfoEntries, contextTimeInfoEntries } = fetchTimeInfo(); @@ -129,7 +134,7 @@ export default class NodeWatchFileSystem implements WatchFileSystem { if (items && this.inputFileSystem && this.inputFileSystem.purge) { const fs = this.inputFileSystem; for (const item of items) { - fs.purge(item); + fs.purge?.(item); } } return items; @@ -143,7 +148,7 @@ export default class NodeWatchFileSystem implements WatchFileSystem { if (items && this.inputFileSystem && this.inputFileSystem.purge) { const fs = this.inputFileSystem; for (const item of items) { - fs.purge(item); + fs.purge?.(item); } } return items; @@ -172,12 +177,12 @@ export default class NodeWatchFileSystem implements WatchFileSystem { const fs = this.inputFileSystem; if (removals) { for (const item of removals) { - fs.purge(item); + fs.purge?.(item); } } if (changes) { for (const item of changes) { - fs.purge(item); + fs.purge?.(item); } } } diff --git a/packages/rspack/src/util/fs.ts b/packages/rspack/src/util/fs.ts index 21170a82799..ba3466492c8 100644 --- a/packages/rspack/src/util/fs.ts +++ b/packages/rspack/src/util/fs.ts @@ -9,6 +9,7 @@ */ import assert from "node:assert"; +import { Abortable } from "node:events"; import path from "node:path"; import type { WatchOptions } from "../config"; @@ -30,7 +31,7 @@ export interface WatcherInfo { contextTimeInfoEntries: Map; // get info about directories } -interface IDirent { +export type IStatsBase = { isFile: () => boolean; isDirectory: () => boolean; isBlockDevice: () => boolean; @@ -38,10 +39,36 @@ interface IDirent { isSymbolicLink: () => boolean; isFIFO: () => boolean; isSocket: () => boolean; - name: string | Buffer; -} + dev: T; + ino: T; + mode: T; + nlink: T; + uid: T; + gid: T; + rdev: T; + size: T; + blksize: T; + blocks: T; + atimeMs: T; + mtimeMs: T; + ctimeMs: T; + birthtimeMs: T; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; +}; -interface IStats { +export type IStats = IStatsBase; + +export type IBigIntStats = IStatsBase & { + atimeNs: bigint; + mtimeNs: bigint; + ctimeNs: bigint; + birthtimeNs: bigint; +}; + +interface IDirent { isFile: () => boolean; isDirectory: () => boolean; isBlockDevice: () => boolean; @@ -49,24 +76,7 @@ interface IStats { isSymbolicLink: () => boolean; isFIFO: () => boolean; isSocket: () => boolean; - dev: number | bigint; - ino: number | bigint; - mode: number | bigint; - nlink: number | bigint; - uid: number | bigint; - gid: number | bigint; - rdev: number | bigint; - size: number | bigint; - blksize: number | bigint; - blocks: number | bigint; - atimeMs: number | bigint; - mtimeMs: number | bigint; - ctimeMs: number | bigint; - birthtimeMs: number | bigint; - atime: Date; - mtime: Date; - ctime: Date; - birthtime: Date; + name: string | Buffer; } export interface OutputFileSystem { @@ -111,6 +121,365 @@ export interface OutputFileSystem { dirname?: (arg0: string) => string; } +export type JsonPrimitive = string | number | boolean | null; +export type JsonArray = JsonValue[]; +export type JsonValue = JsonPrimitive | JsonObject | JsonArray; +export type JsonObject = { [Key in string]: JsonValue } & { + [Key in string]?: JsonValue | undefined; +}; + +export type NoParamCallback = (err: NodeJS.ErrnoException | null) => void; +export type StringCallback = ( + err: NodeJS.ErrnoException | null, + data?: string +) => void; +export type BufferCallback = ( + err: NodeJS.ErrnoException | null, + data?: Buffer +) => void; +export type StringOrBufferCallback = ( + err: NodeJS.ErrnoException | null, + data?: string | Buffer +) => void; +export type ReaddirStringCallback = ( + err: NodeJS.ErrnoException | null, + files?: string[] +) => void; +export type ReaddirBufferCallback = ( + err: NodeJS.ErrnoException | null, + files?: Buffer[] +) => void; +export type ReaddirStringOrBufferCallback = ( + err: NodeJS.ErrnoException | null, + files?: string[] | Buffer[] +) => void; +export type ReaddirDirentCallback = ( + err: NodeJS.ErrnoException | null, + files?: IDirent[] +) => void; +export type StatsCallback = ( + err: NodeJS.ErrnoException | null, + stats?: IStats +) => void; +export type BigIntStatsCallback = ( + err: NodeJS.ErrnoException | null, + stats?: IBigIntStats +) => void; +export type StatsOrBigIntStatsCallback = ( + err: NodeJS.ErrnoException | null, + stats?: IStats | IBigIntStats +) => void; +export type NumberCallback = ( + err: NodeJS.ErrnoException | null, + data?: number +) => void; +export type ReadJsonCallback = ( + err: NodeJS.ErrnoException | Error | null, + data?: JsonObject +) => void; + +export type PathLike = string | Buffer | URL; +export type PathOrFileDescriptor = PathLike | number; + +export type ObjectEncodingOptions = { + encoding?: BufferEncoding | null; +}; + +export type ReadFile = { + ( + path: PathOrFileDescriptor, + options: + | ({ + encoding: null | undefined; + flag?: string; + } & Abortable) + | null + | undefined, + callback: BufferCallback + ): void; + ( + path: PathOrFileDescriptor, + options: + | ({ encoding: BufferEncoding; flag?: string } & Abortable) + | BufferEncoding, + callback: StringCallback + ): void; + ( + path: PathOrFileDescriptor, + options: + | (ObjectEncodingOptions & { flag?: string } & Abortable) + | BufferEncoding + | null + | undefined, + callback: StringOrBufferCallback + ): void; + (path: PathOrFileDescriptor, callback: BufferCallback): void; +}; + +export type ReadFileSync = { + ( + path: PathOrFileDescriptor, + options: { + encoding: null | undefined; + flag?: string; + } | null + ): Buffer; + ( + path: PathOrFileDescriptor, + options: { encoding: BufferEncoding; flag?: string } | BufferEncoding + ): string; + ( + path: PathOrFileDescriptor, + options: (ObjectEncodingOptions & { flag?: string }) | BufferEncoding | null + ): string | Buffer; +}; + +export type EncodingOption = + | ObjectEncodingOptions + | BufferEncoding + | undefined + | null; + +export type BufferEncodingOption = "buffer" | { encoding: "buffer" }; + +export type StatOptions = { + bigint?: boolean; +}; + +export type StatSyncOptions = { + bigint?: boolean; + throwIfNoEntry?: boolean; +}; + +export type Readlink = { + (path: PathLike, options: EncodingOption, callback: StringCallback): void; + ( + path: PathLike, + options: BufferEncodingOption, + callback: BufferCallback + ): void; + ( + path: PathLike, + options: EncodingOption, + callback: StringOrBufferCallback + ): void; + (path: PathLike, callback: StringCallback): void; +}; + +export type ReadlinkSync = { + (path: PathLike, options: EncodingOption): string; + (path: PathLike, options: BufferEncodingOption): Buffer; + (path: PathLike, options: EncodingOption): string | Buffer; +}; + +export type Readdir = { + ( + path: PathLike, + options: + | { + encoding: BufferEncoding | null; + withFileTypes?: false; + recursive?: boolean; + } + | BufferEncoding + | null + | undefined, + callback: ReaddirStringCallback + ): void; + ( + path: PathLike, + options: + | { encoding: "buffer"; withFileTypes?: false; recursive?: boolean } + | "buffer", + callback: ReaddirBufferCallback + ): void; + (path: PathLike, callback: ReaddirStringCallback): void; + ( + path: PathLike, + options: + | (ObjectEncodingOptions & { withFileTypes: true; recursive?: boolean }) + | BufferEncoding + | null + | undefined, + callback: ReaddirStringOrBufferCallback + ): void; + ( + path: PathLike, + options: ObjectEncodingOptions & { + withFileTypes: true; + recursive?: boolean; + }, + callback: ReaddirDirentCallback + ): void; +}; + +export type ReaddirSync = { + ( + path: PathLike, + options: + | { + encoding: BufferEncoding | null; + withFileTypes?: false; + recursive?: boolean; + } + | BufferEncoding + | null + ): string[]; + ( + path: PathLike, + options: + | { encoding: "buffer"; withFileTypes?: false; recursive?: boolean } + | "buffer" + ): Buffer[]; + ( + path: PathLike, + options: + | (ObjectEncodingOptions & { withFileTypes?: false; recursive?: boolean }) + | BufferEncoding + | null + ): string[] | Buffer[]; + ( + path: PathLike, + options: ObjectEncodingOptions & { + withFileTypes: true; + recursive?: boolean; + } + ): IDirent[]; +}; + +export type Stat = { + (path: PathLike, callback: StatsCallback): void; + ( + path: PathLike, + options: (StatOptions & { bigint?: false }) | undefined, + callback: StatsCallback + ): void; + ( + path: PathLike, + options: StatOptions & { bigint: true }, + callback: BigIntStatsCallback + ): void; + ( + path: PathLike, + options: StatOptions | undefined, + callback: StatsOrBigIntStatsCallback + ): void; +}; + +export type StatSync = { + (path: PathLike, options?: undefined): IStats; + ( + path: PathLike, + options?: StatSyncOptions & { bigint?: false; throwIfNoEntry: false } + ): IStats | undefined; + ( + path: PathLike, + options: StatSyncOptions & { bigint: true; throwIfNoEntry: false } + ): IBigIntStats | undefined; + (path: PathLike, options?: StatSyncOptions & { bigint?: false }): IStats; + (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats; + ( + path: PathLike, + options: StatSyncOptions & { bigint: boolean; throwIfNoEntry?: false } + ): IStats | IBigIntStats; + ( + path: PathLike, + options?: StatSyncOptions + ): IStats | IBigIntStats | undefined; +}; + +export type LStat = { + (path: PathLike, callback: StatsCallback): void; + ( + path: PathLike, + options: (StatOptions & { bigint?: false }) | undefined, + callback: StatsCallback + ): void; + ( + path: PathLike, + options: StatOptions & { bigint: true }, + callback: BigIntStatsCallback + ): void; + ( + path: PathLike, + options: StatOptions | undefined, + callback: StatsOrBigIntStatsCallback + ): void; +}; + +export type LStatSync = { + (path: PathLike, options?: undefined): IStats; + ( + path: PathLike, + options?: StatSyncOptions & { bigint?: false; throwIfNoEntry: false } + ): IStats | undefined; + ( + path: PathLike, + options: StatSyncOptions & { bigint: true; throwIfNoEntry: false } + ): IBigIntStats | undefined; + (path: PathLike, options?: StatSyncOptions & { bigint?: false }): IStats; + (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats; + ( + path: PathLike, + options: StatSyncOptions & { bigint: boolean; throwIfNoEntry?: false } + ): IStats | IBigIntStats; + ( + path: PathLike, + options?: StatSyncOptions + ): IStats | IBigIntStats | undefined; +}; + +export type RealPath = { + (path: PathLike, options: EncodingOption, callback: StringCallback): void; + ( + path: PathLike, + options: BufferEncodingOption, + callback: BufferCallback + ): void; + ( + path: PathLike, + options: EncodingOption, + callback: StringOrBufferCallback + ): void; + (path: PathLike, callback: StringCallback): void; +}; + +export type RealPathSync = { + (path: PathLike, options?: EncodingOption): string; + (path: PathLike, options: BufferEncodingOption): Buffer; + (path: PathLike, options?: EncodingOption): string | Buffer; +}; + +export type ReadJson = ( + path: PathOrFileDescriptor, + callback: ReadJsonCallback +) => void; + +export type ReadJsonSync = (path: PathOrFileDescriptor) => JsonObject; + +export type Purge = (files?: string | string[] | Set) => void; + +export type InputFileSystem = { + readFile: ReadFile; + readFileSync?: ReadFileSync; + readlink: Readlink; + readlinkSync?: ReadlinkSync; + readdir: Readdir; + readdirSync?: ReaddirSync; + stat: Stat; + statSync?: StatSync; + lstat?: LStat; + lstatSync?: LStatSync; + realpath?: RealPath; + realpathSync?: RealPathSync; + readJson?: ReadJson; + readJsonSync?: ReadJsonSync; + purge?: Purge; + join?: (path1: string, path2: string) => string; + relative?: (from: string, to: string) => string; + dirname?: (path: string) => string; +}; + export function rmrf( fs: OutputFileSystem, p: string, From 926db794fe43824a27ae05617e6f094856f7f9c8 Mon Sep 17 00:00:00 2001 From: ForAeons Date: Sat, 10 Aug 2024 21:50:19 +0800 Subject: [PATCH 2/2] fix: update type import --- packages/rspack/src/util/fs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rspack/src/util/fs.ts b/packages/rspack/src/util/fs.ts index ba3466492c8..3609b1f271f 100644 --- a/packages/rspack/src/util/fs.ts +++ b/packages/rspack/src/util/fs.ts @@ -9,7 +9,7 @@ */ import assert from "node:assert"; -import { Abortable } from "node:events"; +import type { Abortable } from "node:events"; import path from "node:path"; import type { WatchOptions } from "../config";