ripstat
Version:
Fetch the stats for a file as if a saber-tooth tiger is chasing you!
66 lines (35 loc) • 1.53 kB
text/typescript
/* IMPORT */
import {toNamespacedPath} from 'node:path';
import process from 'node:process';
import fs from 'stubborn-fs';
import {RETRY_TIMEOUT} from './constants';
import Stats from './stats';
/* HELPERS */
const {stat, FSReqCallback} = process['binding']( 'fs' );
/* MAIN */
const ripstat = ( filePath: string, timeout?: number ): Promise<Stats> => {
return new Promise<Stats> ( ( resolve, reject ) => {
const req = new FSReqCallback ( true );
req.oncomplete = ( error: NodeJS.ErrnoException, statsdata: bigint[] ): void => {
if ( error ) {
const {code} = error;
if ( code === 'EMFILE' || code === 'ENFILE' || code === 'EAGAIN' || code === 'EBUSY' || code === 'EACCESS' || code === 'EACCS' || code === 'EPERM' ) { // Retriable error
fs.retry.stat ( timeout || RETRY_TIMEOUT )( filePath, { bigint: true } ).then ( nstats => {
const statsdata = [nstats.dev, nstats.mode, nstats.nlink, nstats.uid, nstats.gid, nstats.rdev, nstats.blksize, nstats.ino, nstats.size, nstats.blocks, 0n, nstats.atimeNs, 0n, nstats.mtimeNs, 0n, nstats.ctimeNs, 0n, nstats.birthtimeNs];
const stats = new Stats ( statsdata );
resolve ( stats );
}, reject );
} else {
reject ( error );
}
} else {
const stats = new Stats ( statsdata );
resolve ( stats );
}
};
stat ( toNamespacedPath ( filePath ), true, req );
});
};
/* EXPORT */
export default ripstat;
export type {Stats};