Skip to content

Commit

Permalink
Merge pull request #416 from mrmlnc/some_refactor
Browse files Browse the repository at this point in the history
Minor changes after updating configs
  • Loading branch information
mrmlnc committed Aug 4, 2023
2 parents 1a7cf04 + 8b20cd4 commit 1bbcfa9
Show file tree
Hide file tree
Showing 22 changed files with 137 additions and 105 deletions.
43 changes: 26 additions & 17 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import * as taskManager from './managers/tasks';
import ProviderAsync from './providers/async';
import ProviderStream from './providers/stream';
import ProviderSync from './providers/sync';
import Settings from './settings';
import * as utils from './utils';
import { ProviderAsync, ProviderStream, ProviderSync } from './providers';
import { ReaderAsync, ReaderStream, ReaderSync } from './readers';

import type { Options as OptionsInternal } from './settings';
import type { Entry as EntryInternal, EntryItem, FileSystemAdapter as FileSystemAdapterInternal, Pattern as PatternInternal } from './types';
import type Provider from './providers/provider';

type EntryObjectModePredicate = { [TKey in keyof Pick<OptionsInternal, 'objectMode'>]-?: true };
type EntryStatsPredicate = { [TKey in keyof Pick<OptionsInternal, 'stats'>]-?: true };
Expand All @@ -18,11 +16,16 @@ function FastGlob(source: PatternInternal | PatternInternal[], options?: Options
async function FastGlob(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Promise<EntryItem[]> {
assertPatternsInput(source);

const works = getWorks(source, ProviderAsync, options);
const settings = new Settings(options);
const reader = new ReaderAsync(settings);
const provider = new ProviderAsync(reader, settings);

const tasks = getTasks(source, settings);
const promises = tasks.map((task) => provider.read(task));

const result = await Promise.all(works);
const result = await Promise.all(promises);

return utils.array.flatten(result);
return utils.array.flatFirstLevel(result);
}

namespace FastGlob {
Expand All @@ -43,22 +46,32 @@ namespace FastGlob {
export function sync(source: PatternInternal | PatternInternal[], options?: OptionsInternal): EntryItem[] {
assertPatternsInput(source);

const works = getWorks(source, ProviderSync, options);
const settings = new Settings(options);
const reader = new ReaderSync(settings);
const provider = new ProviderSync(reader, settings);

const tasks = getTasks(source, settings);
const entries = tasks.map((task) => provider.read(task));

return utils.array.flatten(works);
return utils.array.flatFirstLevel(entries);
}

export function stream(source: PatternInternal | PatternInternal[], options?: OptionsInternal): NodeJS.ReadableStream {
assertPatternsInput(source);

const works = getWorks(source, ProviderStream, options);
const settings = new Settings(options);
const reader = new ReaderStream(settings);
const provider = new ProviderStream(reader, settings);

const tasks = getTasks(source, settings);
const streams = tasks.map((task) => provider.read(task));

/**
* The stream returned by the provider cannot work with an asynchronous iterator.
* To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams.
* This affects performance (+25%). I don't see best solution right now.
*/
return utils.stream.merge(works);
return utils.stream.merge(streams);
}

export function generateTasks(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Task[] {
Expand Down Expand Up @@ -119,14 +132,10 @@ namespace FastGlob {
}
}

function getWorks<T>(source: PatternInternal | PatternInternal[], _Provider: new (settings: Settings) => Provider<T>, options?: OptionsInternal): T[] {
function getTasks(source: PatternInternal | PatternInternal[], settings: Settings): taskManager.Task[] {
const patterns = ([] as PatternInternal[]).concat(source);
const settings = new Settings(options);

const tasks = taskManager.generate(patterns, settings);
const provider = new _Provider(settings);

return tasks.map((task) => provider.read(task));
return taskManager.generate(patterns, settings);
}

function assertPatternsInput(input: unknown): never | void {
Expand Down
21 changes: 12 additions & 9 deletions src/providers/async.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@ import * as sinon from 'sinon';

import Settings from '../settings';
import * as tests from '../tests';
import ReaderAsync from '../readers/async';
import ProviderAsync from './async';
import { ReaderAsync } from '../readers';
import { ProviderAsync } from './async';

import type { IReaderAsync } from '../readers';
import type { Options } from '../settings';
import type { Entry, EntryItem, ErrnoException } from '../types';
import type ReaderStream from '../readers/stream';
import type { Task } from '../managers/tasks';

type StubbedReaderAsync = sinon.SinonStubbedInstance<IReaderAsync>;

class TestProvider extends ProviderAsync {
protected override _reader: ReaderAsync = sinon.createStubInstance(ReaderAsync) as unknown as ReaderAsync;
public readonly reader: StubbedReaderAsync;

constructor(options?: Options) {
super(new Settings(options));
}
constructor(
options?: Options,
reader: StubbedReaderAsync = sinon.createStubInstance(ReaderAsync),
) {
super(reader, new Settings(options));

public get reader(): sinon.SinonStubbedInstance<ReaderStream> {
return this._reader as unknown as sinon.SinonStubbedInstance<ReaderStream>;
this.reader = reader;
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/providers/async.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import ReaderAsync from '../readers/async';
import Provider from './provider';
import { Provider } from './provider';

import type { IReaderAsync } from '../readers';
import type Settings from '../settings';
import type { Task } from '../managers/tasks';
import type { Entry, EntryItem, ReaderOptions } from '../types';

export default class ProviderAsync extends Provider<Promise<EntryItem[]>> {
protected _reader: ReaderAsync;
export class ProviderAsync extends Provider<Promise<EntryItem[]>> {
#reader: IReaderAsync;

constructor(settings: Settings) {
constructor(reader: IReaderAsync, settings: Settings) {
super(settings);

this._reader = new ReaderAsync(settings);
this.#reader = reader;
}

public async read(task: Task): Promise<EntryItem[]> {
Expand All @@ -25,9 +25,9 @@ export default class ProviderAsync extends Provider<Promise<EntryItem[]>> {

public api(root: string, task: Task, options: ReaderOptions): Promise<Entry[]> {
if (task.dynamic) {
return this._reader.dynamic(root, options);
return this.#reader.dynamic(root, options);
}

return this._reader.static(task.patterns, options);
return this.#reader.static(task.patterns, options);
}
}
3 changes: 3 additions & 0 deletions src/providers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './async';
export * from './stream';
export * from './sync';
2 changes: 1 addition & 1 deletion src/providers/provider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from 'node:path';

import Settings from '../settings';
import * as tests from '../tests';
import Provider from './provider';
import { Provider } from './provider';

import type { Task } from '../managers/tasks';
import type { Options } from '../settings';
Expand Down
2 changes: 1 addition & 1 deletion src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type Settings from '../settings';
import type { MicromatchOptions, ReaderOptions } from '../types';
import type { Task } from '../managers/tasks';

export default abstract class Provider<T> {
export abstract class Provider<T> {
public readonly errorFilter: ErrorFilter;
public readonly entryFilter: EntryFilter;
public readonly deepFilter: DeepFilter;
Expand Down
20 changes: 12 additions & 8 deletions src/providers/stream.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,28 @@ import { PassThrough } from 'node:stream';

import * as sinon from 'sinon';

import ReaderStream from '../readers/stream';
import Settings from '../settings';
import * as tests from '../tests';
import ProviderStream from './stream';
import { ProviderStream } from './stream';
import { ReaderStream } from '../readers';

import type { IReaderStream } from '../readers';
import type { Options } from '../settings';
import type { Entry, EntryItem, ErrnoException } from '../types';
import type { Task } from '../managers/tasks';

type StubbedReaderStream = sinon.SinonStubbedInstance<IReaderStream>;

class TestProvider extends ProviderStream {
protected override _reader: ReaderStream = sinon.createStubInstance(ReaderStream) as unknown as ReaderStream;
public readonly reader: StubbedReaderStream;

constructor(options?: Options) {
super(new Settings(options));
}
constructor(
options?: Options,
reader: StubbedReaderStream = sinon.createStubInstance(ReaderStream),
) {
super(reader, new Settings(options));

public get reader(): sinon.SinonStubbedInstance<ReaderStream> {
return this._reader as unknown as sinon.SinonStubbedInstance<ReaderStream>;
this.reader = reader;
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/providers/stream.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { Readable } from 'node:stream';

import ReaderStream from '../readers/stream';
import Provider from './provider';
import { Provider } from './provider';

import type { IReaderStream } from '../readers';
import type Settings from '../settings';
import type { Task } from '../managers/tasks';
import type { Entry, ErrnoException, ReaderOptions } from '../types';

export default class ProviderStream extends Provider<Readable> {
protected _reader: ReaderStream;
export class ProviderStream extends Provider<Readable> {
#reader: IReaderStream;

constructor(settings: Settings) {
constructor(reader: IReaderStream, settings: Settings) {
super(settings);

this._reader = new ReaderStream(settings);
this.#reader = reader;
}

public read(task: Task): Readable {
Expand All @@ -36,9 +36,9 @@ export default class ProviderStream extends Provider<Readable> {

public api(root: string, task: Task, options: ReaderOptions): Readable {
if (task.dynamic) {
return this._reader.dynamic(root, options);
return this.#reader.dynamic(root, options);
}

return this._reader.static(task.patterns, options);
return this.#reader.static(task.patterns, options);
}
}
20 changes: 12 additions & 8 deletions src/providers/sync.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@ import * as assert from 'node:assert';

import * as sinon from 'sinon';

import ReaderSync from '../readers/sync';
import { ReaderSync } from '../readers';
import Settings from '../settings';
import * as tests from '../tests';
import ProviderSync from './sync';
import { ProviderSync } from './sync';

import type { IReaderSync } from '../readers';
import type { Options } from '../settings';

type StubbedReaderSync = sinon.SinonStubbedInstance<IReaderSync>;

class TestProvider extends ProviderSync {
protected override _reader: ReaderSync = sinon.createStubInstance(ReaderSync) as unknown as ReaderSync;
public readonly reader: StubbedReaderSync;

constructor(options?: Options) {
super(new Settings(options));
}
constructor(
options?: Options,
reader: StubbedReaderSync = sinon.createStubInstance(ReaderSync),
) {
super(reader, new Settings(options));

public get reader(): sinon.SinonStubbedInstance<ReaderSync> {
return this._reader as unknown as sinon.SinonStubbedInstance<ReaderSync>;
this.reader = reader;
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/providers/sync.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import ReaderSync from '../readers/sync';
import Provider from './provider';
import { Provider } from './provider';

import type { IReaderSync } from '../readers';
import type Settings from '../settings';
import type { Task } from '../managers/tasks';
import type { Entry, EntryItem, ReaderOptions } from '../types';

export default class ProviderSync extends Provider<EntryItem[]> {
protected _reader: ReaderSync;
export class ProviderSync extends Provider<EntryItem[]> {
#reader: IReaderSync;

constructor(settings: Settings) {
constructor(reader: IReaderSync, settings: Settings) {
super(settings);

this._reader = new ReaderSync(settings);
this.#reader = reader;
}

public read(task: Task): EntryItem[] {
Expand All @@ -25,9 +25,9 @@ export default class ProviderSync extends Provider<EntryItem[]> {

public api(root: string, task: Task, options: ReaderOptions): Entry[] {
if (task.dynamic) {
return this._reader.dynamic(root, options);
return this.#reader.dynamic(root, options);
}

return this._reader.static(task.patterns, options);
return this.#reader.static(task.patterns, options);
}
}
4 changes: 2 additions & 2 deletions src/readers/async.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import * as sinon from 'sinon';

import Settings from '../settings';
import * as tests from '../tests';
import ReaderAsync from './async';
import ReaderStream from './stream';
import { ReaderAsync } from './async';
import { ReaderStream } from './stream';

import type { Options } from '../settings';
import type { ReaderOptions } from '../types';
Expand Down
24 changes: 12 additions & 12 deletions src/readers/async.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import * as fsWalk from '@nodelib/fs.walk';

import Reader from './reader';
import ReaderStream from './stream';
import { Reader } from './reader';
import { ReaderStream } from './stream';

import type Settings from '../settings';
import type { Entry, ReaderOptions, Pattern } from '../types';

export default class ReaderAsync extends Reader<Promise<Entry[]>> {
export interface IReaderAsync {
dynamic: (root: string, options: ReaderOptions) => Promise<Entry[]>;
static: (patterns: Pattern[], options: ReaderOptions) => Promise<Entry[]>;
}

export class ReaderAsync extends Reader<Promise<Entry[]>> implements IReaderAsync {
protected _walkAsync: typeof fsWalk.walk = fsWalk.walk;
protected _readerStream: ReaderStream;

Expand All @@ -31,15 +36,10 @@ export default class ReaderAsync extends Reader<Promise<Entry[]>> {
public async static(patterns: Pattern[], options: ReaderOptions): Promise<Entry[]> {
const entries: Entry[] = [];

const stream = this._readerStream.static(patterns, options);
for await (const entry of this._readerStream.static(patterns, options)) {
entries.push(entry as Entry);
}

// After #235, replace it with an asynchronous iterator.
return new Promise((resolve, reject) => {
stream.once('error', reject);
stream.on('data', (entry: Entry) => entries.push(entry));
stream.once('end', () => {
resolve(entries);
});
});
return entries;
}
}
3 changes: 3 additions & 0 deletions src/readers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './async';
export * from './stream';
export * from './sync';
2 changes: 1 addition & 1 deletion src/readers/reader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as path from 'node:path';
import { Stats, StatsMode } from '@nodelib/fs.macchiato';

import Settings from '../settings';
import Reader from './reader';
import { Reader } from './reader';

import type { Options } from '../settings';
import type { Entry, FsStats, Pattern } from '../types';
Expand Down
Loading

0 comments on commit 1bbcfa9

Please sign in to comment.