view-ignored 0.10.1 → 0.11.0

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.
Files changed (68) hide show
  1. package/README.md +116 -62
  2. package/out/browser.d.ts +1 -0
  3. package/out/browser.js +1 -0
  4. package/out/browser_scan.d.ts +1 -3
  5. package/out/browser_scan.js +11 -46
  6. package/out/browser_stream.d.ts +6 -1
  7. package/out/browser_stream.js +6 -1
  8. package/out/index.d.ts +1 -0
  9. package/out/index.js +1 -0
  10. package/out/patterns/extractor.d.ts +7 -7
  11. package/out/patterns/gitignore.d.ts +2 -2
  12. package/out/patterns/gitignore.js +14 -6
  13. package/out/patterns/ignores.d.ts +17 -8
  14. package/out/patterns/index.d.ts +1 -0
  15. package/out/patterns/index.js +1 -0
  16. package/out/patterns/init.d.ts +2 -2
  17. package/out/patterns/initState.d.ts +0 -7
  18. package/out/patterns/jsrjson.d.ts +2 -3
  19. package/out/patterns/jsrjson.js +25 -38
  20. package/out/patterns/matcherContext.d.ts +12 -9
  21. package/out/patterns/matcherContextPatch.js +153 -73
  22. package/out/patterns/matcherStream.d.ts +30 -11
  23. package/out/patterns/matcherStream.js +70 -25
  24. package/out/patterns/packagejson.d.ts +2 -2
  25. package/out/patterns/packagejson.js +11 -14
  26. package/out/patterns/patternCompile.js +35 -37
  27. package/out/patterns/patternList.d.ts +6 -2
  28. package/out/patterns/patternList.js +8 -3
  29. package/out/patterns/resolveSources.d.ts +22 -5
  30. package/out/patterns/resolveSources.js +153 -97
  31. package/out/patterns/resource.d.ts +16 -0
  32. package/out/patterns/resource.js +1 -0
  33. package/out/patterns/rule.d.ts +59 -11
  34. package/out/patterns/rule.js +101 -64
  35. package/out/patterns/source.d.ts +9 -17
  36. package/out/scan.d.ts +11 -3
  37. package/out/scan.js +16 -4
  38. package/out/scanCb.d.ts +16 -0
  39. package/out/scanCb.js +73 -0
  40. package/out/scanParallel.d.ts +18 -0
  41. package/out/scanParallel.js +146 -0
  42. package/out/stream.d.ts +6 -1
  43. package/out/stream.js +7 -2
  44. package/out/targets/bun.js +43 -36
  45. package/out/targets/deno.js +25 -23
  46. package/out/targets/git.js +3 -3
  47. package/out/targets/jsr.js +25 -23
  48. package/out/targets/jsrManifest.d.ts +8 -7
  49. package/out/targets/jsrManifest.js +40 -9
  50. package/out/targets/npm.js +30 -23
  51. package/out/targets/npmManifest.d.ts +18 -46
  52. package/out/targets/npmManifest.js +96 -23
  53. package/out/targets/target.d.ts +8 -16
  54. package/out/targets/vsce.js +20 -27
  55. package/out/targets/vsceManifest.d.ts +7 -0
  56. package/out/targets/vsceManifest.js +18 -0
  57. package/out/targets/yarn.js +48 -39
  58. package/out/targets/yarnClassic.js +20 -18
  59. package/out/types.d.ts +8 -7
  60. package/out/unixify.d.ts +1 -1
  61. package/out/unixify.js +40 -21
  62. package/out/walk.d.ts +42 -4
  63. package/out/walk.js +146 -92
  64. package/package.json +25 -22
  65. package/out/getDepth.d.ts +0 -4
  66. package/out/getDepth.js +0 -21
  67. package/out/opendir.d.ts +0 -3
  68. package/out/opendir.js +0 -28
@@ -48,7 +48,7 @@ export type MatchKind = RuleMatch["kind"];
48
48
  *
49
49
  * @since 0.9.1
50
50
  */
51
- export interface RuleMatchBase<K extends string> {
51
+ export interface RuleMatchBase<K extends string | number | symbol> {
52
52
  kind: K;
53
53
  ignored: boolean;
54
54
  }
@@ -57,7 +57,7 @@ export interface RuleMatchBase<K extends string> {
57
57
  *
58
58
  * @since 0.9.1
59
59
  */
60
- export interface RuleMatchBaseSource<K extends string> extends RuleMatchBase<K> {
60
+ export interface RuleMatchBaseSource<K extends string | number | symbol> extends RuleMatchBase<K> {
61
61
  source: Source;
62
62
  }
63
63
  /**
@@ -65,30 +65,72 @@ export interface RuleMatchBaseSource<K extends string> extends RuleMatchBase<K>
65
65
  *
66
66
  * @since 0.9.1
67
67
  */
68
- export interface RuleMatchBasePattern<K extends string> extends RuleMatchBase<K> {
68
+ export interface RuleMatchBasePattern<K extends string | number | symbol> extends RuleMatchBase<K> {
69
69
  pattern: string;
70
70
  }
71
71
  /**
72
72
  * @see {@link RuleMatch}
73
73
  *
74
- * @since 0.9.1
74
+ * @since 0.11.0
75
75
  */
76
- export interface RuleMatchBaseErrorPattern<K extends string> extends RuleMatchBasePattern<K> {
76
+ export interface RuleMatchBaseError<K extends string | number | symbol> extends RuleMatchBase<K> {
77
77
  error: Error;
78
78
  }
79
+ /**
80
+ * @see {@link RuleMatch}
81
+ *
82
+ * @since 0.11.0
83
+ */
84
+ export interface RuleMatchBaseInvalidSource<K extends string | number | symbol> extends RuleMatchBaseError<K>, RuleMatchBaseSource<K> {
85
+ }
86
+ /**
87
+ * @see {@link RuleMatch}
88
+ *
89
+ * @since 0.11.0
90
+ */
91
+ export interface RuleMatchBaseInvalidPattern<K extends string | number | symbol> extends RuleMatchBasePattern<K>, RuleMatchBaseError<K> {
92
+ }
93
+ /**
94
+ * @see {@link RuleMatch}
95
+ *
96
+ * @since 0.11.0
97
+ */
98
+ export interface RuleMatchBaseInvalidExternal<K extends string | number | symbol> extends RuleMatchBaseInvalidPattern<K>, RuleMatchBaseSource<K> {
99
+ }
79
100
  /**
80
101
  * @see {@link RuleMatch}
81
102
  *
82
103
  * @since 0.9.1
83
104
  */
84
- export interface RuleMatchBaseSourcePattern<K extends string> extends RuleMatchBasePattern<K>, RuleMatchBaseSource<K> {
105
+ export interface RuleMatchBaseExternal<K extends string | number | symbol> extends RuleMatchBasePattern<K>, RuleMatchBaseSource<K> {
106
+ }
107
+ /**
108
+ * The kind of a pattern match.
109
+ *
110
+ * @since 0.11.0
111
+ */
112
+ export declare const enum RuleMatchKind {
113
+ "none" = 0,
114
+ "missingSource" = 1,
115
+ "noMatch" = 2,
116
+ "invalidSource" = 3,
117
+ "invalidExternal" = 4,
118
+ "invalidInternal" = 5,
119
+ "external" = 6,
120
+ "internal" = 7
85
121
  }
86
122
  /**
87
123
  * @see {@link ruleTest}
88
124
  *
89
125
  * @since 0.6.0
90
126
  */
91
- export type RuleMatch = RuleMatchBase<"none" | "missing-source"> | RuleMatchBaseSource<"no-match" | "broken-source" | "invalid-pattern"> | RuleMatchBaseErrorPattern<"invalid-internal-pattern"> | RuleMatchBasePattern<"internal"> | RuleMatchBaseSourcePattern<"external">;
127
+ export type RuleMatch = RuleMatchBase<RuleMatchKind.none> | RuleMatchBase<RuleMatchKind.missingSource> | RuleMatchBaseSource<RuleMatchKind.noMatch> | RuleMatchBaseInvalidSource<RuleMatchKind.invalidSource> | RuleMatchBaseInvalidExternal<RuleMatchKind.invalidExternal> | RuleMatchBaseInvalidPattern<RuleMatchKind.invalidInternal> | RuleMatchBaseExternal<RuleMatchKind.external> | RuleMatchBasePattern<RuleMatchKind.internal>;
128
+ /**
129
+ * Check if a rule match is invalid.
130
+ *
131
+ * @since 0.11.0
132
+ */
133
+ export declare function isRuleMatchInvalid(match: RuleMatch): match is RuleMatchBaseInvalidSource<RuleMatchKind.invalidSource> | RuleMatchBaseInvalidExternal<RuleMatchKind.invalidExternal> | RuleMatchBaseInvalidPattern<RuleMatchKind.invalidInternal>;
92
134
  /**
93
135
  * @see {@link ruleTest}
94
136
  *
@@ -106,16 +148,22 @@ export interface RuleTestOptions extends PatternFinderOptions {
106
148
  */
107
149
  entry: string;
108
150
  /**
109
- * Result of the `dirname(entry)` call.
151
+ * Pre-lowercased entry path.
110
152
  *
111
- * @since 0.10.1
153
+ * @since 0.11.0
112
154
  */
113
- parentPath: string;
155
+ lowerEntry?: string;
114
156
  }
157
+ /**
158
+ * Synchronous version of {@link ruleTest}.
159
+ *
160
+ * @since 0.11.0
161
+ */
162
+ export declare function ruleTestSync(options: RuleTestOptions): RuleMatch;
115
163
  /**
116
164
  * Checks whether a given entry should be ignored based on internal and external patterns.
117
165
  * Populates unknown sources using {@link resolveSources}.
118
166
  *
119
167
  * @since 0.6.0
120
168
  */
121
- export declare function ruleTest(options: RuleTestOptions): Promise<RuleMatch>;
169
+ export declare function ruleTest(options: RuleTestOptions, cb: (err: Error | null, match: RuleMatch) => void): void;
@@ -1,67 +1,119 @@
1
1
  import { patternCacheTest } from "./patternList.js";
2
- function cacheTest(rs, path) {
3
- for (const r of rs) {
2
+ /**
3
+ * The kind of a pattern match.
4
+ *
5
+ * @since 0.11.0
6
+ */
7
+ export var RuleMatchKind;
8
+ (function (RuleMatchKind) {
9
+ RuleMatchKind[RuleMatchKind["none"] = 0] = "none";
10
+ RuleMatchKind[RuleMatchKind["missingSource"] = 1] = "missingSource";
11
+ RuleMatchKind[RuleMatchKind["noMatch"] = 2] = "noMatch";
12
+ RuleMatchKind[RuleMatchKind["invalidSource"] = 3] = "invalidSource";
13
+ RuleMatchKind[RuleMatchKind["invalidExternal"] = 4] = "invalidExternal";
14
+ RuleMatchKind[RuleMatchKind["invalidInternal"] = 5] = "invalidInternal";
15
+ RuleMatchKind[RuleMatchKind["external"] = 6] = "external";
16
+ RuleMatchKind[RuleMatchKind["internal"] = 7] = "internal";
17
+ })(RuleMatchKind || (RuleMatchKind = {}));
18
+ /**
19
+ * Check if a rule match is invalid.
20
+ *
21
+ * @since 0.11.0
22
+ */
23
+ export function isRuleMatchInvalid(match) {
24
+ const k = match.kind;
25
+ return (k === RuleMatchKind.invalidSource ||
26
+ k === RuleMatchKind.invalidExternal ||
27
+ k === RuleMatchKind.invalidInternal);
28
+ }
29
+ function cacheTest(rs, path, matchCtx) {
30
+ const len = rs.length;
31
+ for (let i = 0; i < len; i++) {
32
+ const r = rs[i];
4
33
  try {
5
- if (patternCacheTest(r, path)) {
6
- return [r.pattern, undefined];
34
+ if (patternCacheTest(r, path, matchCtx)) {
35
+ return r;
7
36
  }
8
37
  }
9
38
  catch (err) {
10
- return [r.pattern, err];
39
+ return err;
11
40
  }
12
41
  }
13
- return ["", undefined];
42
+ return null;
14
43
  }
15
- function testInternal(options, path) {
16
- for (const si of options.target.internalRules) {
17
- const compiled = si.compiled;
18
- if (compiled === null)
44
+ /**
45
+ * Synchronous version of {@link ruleTest}.
46
+ *
47
+ * @since 0.11.0
48
+ */
49
+ export function ruleTestSync(options) {
50
+ const src = options.resource;
51
+ if (src === undefined) {
52
+ throw new Error("view-ignored has crashed: no source cached.");
53
+ }
54
+ if (src === null) {
55
+ return { ignored: false, kind: RuleMatchKind.missingSource };
56
+ }
57
+ if ("error" in src) {
58
+ return { ...src, ignored: true, kind: RuleMatchKind.invalidSource };
59
+ }
60
+ const entry = options.entry;
61
+ const matchCtx = { lower: options.lowerEntry };
62
+ const internalRules = options.target.internalRules;
63
+ for (let i = 0, len = internalRules.length; i < len; i++) {
64
+ const rule = internalRules[i];
65
+ const res = cacheTest(rule.compiled, entry, matchCtx);
66
+ if (res === null)
19
67
  continue;
20
- let [patternMatch, error] = cacheTest(compiled, path);
21
- if (error)
68
+ if (res instanceof Error) {
22
69
  return {
23
- kind: "invalid-internal-pattern",
24
- pattern: patternMatch,
25
- error,
70
+ error: res,
26
71
  ignored: false,
72
+ kind: RuleMatchKind.invalidInternal,
73
+ pattern: "",
27
74
  };
28
- if (patternMatch)
29
- return {
30
- kind: "internal",
31
- pattern: patternMatch,
32
- ignored: si.excludes,
33
- };
75
+ }
76
+ return {
77
+ ignored: rule.excludes,
78
+ kind: RuleMatchKind.internal,
79
+ pattern: res.pattern,
80
+ };
34
81
  }
35
- return null;
36
- }
37
- function testExternal(options, path, source) {
38
- for (const si of source.pattern) {
39
- const compiled = si.compiled;
40
- if (compiled === null) {
82
+ const rules = src.rules;
83
+ const elen = rules.length;
84
+ if (elen === 0) {
85
+ return (src._noMatchCache ??
86
+ (src._noMatchCache = {
87
+ ignored: src.inverted,
88
+ kind: RuleMatchKind.noMatch,
89
+ source: src,
90
+ }));
91
+ }
92
+ for (let i = 0; i < elen; i++) {
93
+ const rule = rules[i];
94
+ const res = cacheTest(rule.compiled, entry, matchCtx);
95
+ if (res === null)
41
96
  continue;
42
- }
43
- let [patternMatch, err] = cacheTest(compiled, path);
44
- if (err) {
45
- source.error = err;
46
- options.ctx?.failed.push(source);
97
+ if (res instanceof Error) {
47
98
  return {
48
- kind: "invalid-pattern",
99
+ error: res,
49
100
  ignored: false,
50
- source,
101
+ kind: RuleMatchKind.invalidExternal,
102
+ pattern: "",
103
+ source: src,
51
104
  };
52
105
  }
53
- if (patternMatch)
54
- return {
55
- kind: "external",
56
- pattern: patternMatch,
57
- ignored: si.excludes,
58
- source,
59
- };
106
+ return {
107
+ ignored: rule.excludes,
108
+ kind: RuleMatchKind.external,
109
+ pattern: res.pattern,
110
+ source: src,
111
+ };
60
112
  }
61
113
  return {
62
- kind: "no-match",
63
- ignored: source.inverted,
64
- source,
114
+ ignored: src.inverted,
115
+ kind: RuleMatchKind.noMatch,
116
+ source: src,
65
117
  };
66
118
  }
67
119
  /**
@@ -70,26 +122,11 @@ function testExternal(options, path, source) {
70
122
  *
71
123
  * @since 0.6.0
72
124
  */
73
- export async function ruleTest(options) {
74
- const parent = options.parentPath;
75
- let source = options.ctx?.external.get(parent);
76
- // if (source === undefined) {
77
- // await resolveSources({ ...options, dir: parent })
78
- // source = options.ctx.external.get(parent)
79
- // }
80
- if (source === undefined) {
81
- throw new Error("view-ignored has crashed: no source cached.");
82
- }
83
- if (source === "none") {
84
- return { kind: "missing-source", ignored: false };
85
- }
86
- if (typeof source === "object" && source.error) {
87
- return { kind: "broken-source", ignored: true, source };
125
+ export function ruleTest(options, cb) {
126
+ try {
127
+ cb(null, ruleTestSync(options));
88
128
  }
89
- let internalMatch = testInternal(options, options.entry);
90
- if (internalMatch !== null) {
91
- return internalMatch;
129
+ catch (err) {
130
+ cb(err, null);
92
131
  }
93
- const externalMatch = testExternal(options, options.entry, source);
94
- return externalMatch;
95
132
  }
@@ -1,25 +1,25 @@
1
- import type { Rule } from "./rule.js";
1
+ import type { Rule, RuleMatch } from "./rule.js";
2
2
  /**
3
3
  * Represents a source of external patterns.
4
4
  *
5
5
  * @since 0.6.0
6
6
  */
7
7
  export type Source = {
8
+ /**
9
+ * @internal
10
+ *
11
+ * @since 0.11.0
12
+ */
13
+ _noMatchCache?: RuleMatch;
8
14
  /**
9
15
  * Patterns defined within the source file.
10
16
  * Those patterns are for ignoring files.
11
17
  *
12
18
  * @see {@link ruleTest}
13
19
  *
14
- * @since 0.6.0
20
+ * @since 0.11.0
15
21
  */
16
- pattern: Rule[];
17
- /**
18
- * Name of the source file.
19
- *
20
- * @since 0.6.0
21
- */
22
- name: string;
22
+ rules: Rule[];
23
23
  /**
24
24
  * Relative path to the source file.
25
25
  *
@@ -36,14 +36,6 @@ export type Source = {
36
36
  * @since 0.6.0
37
37
  */
38
38
  inverted: boolean;
39
- /**
40
- * Error encountered during extraction, if any.
41
- *
42
- * @see {@link ExtractorFn}
43
- *
44
- * @since 0.6.0
45
- */
46
- error?: Error;
47
39
  };
48
40
  /**
49
41
  * Adds a negatable pattern to the source's rules.
package/out/scan.d.ts CHANGED
@@ -4,10 +4,7 @@ export type * from "./types.js";
4
4
  /**
5
5
  * Scan the directory for included files based on the provided targets.
6
6
  *
7
- * Note that this function uses `fs.promises.readFile` and `fs.promises.opendir` without options within
8
- * custom recursion, instead of `fs.promises.readdir` with `{ withFileTypes: true }.
9
7
  * It also normalizes paths to use forward slashes.
10
- * Please report any issues if you encounter problems related to this behavior.
11
8
  *
12
9
  * @param options Scan options.
13
10
  * @returns A promise that resolves to a {@link MatcherContext} containing the scan results.
@@ -15,3 +12,14 @@ export type * from "./types.js";
15
12
  * @since 0.6.0
16
13
  */
17
14
  export declare function scan(options: ScanOptions): Promise<MatcherContext>;
15
+ /**
16
+ * Scan the directory for included files based on the provided targets.
17
+ *
18
+ * It also normalizes paths to use forward slashes.
19
+ *
20
+ * @param options Scan options.
21
+ * @param cb Callback function.
22
+ *
23
+ * @since 0.11.0
24
+ */
25
+ export declare function scanCb(options: ScanOptions, cb: (err: Error | null, ctx: MatcherContext) => void): void;
package/out/scan.js CHANGED
@@ -1,13 +1,11 @@
1
1
  import * as nodefs from "node:fs";
2
2
  import * as process from "node:process";
3
3
  import { scan as browserScan } from "./browser_scan.js";
4
+ import { scanCb as browserScanCb } from "./scanCb.js";
4
5
  /**
5
6
  * Scan the directory for included files based on the provided targets.
6
7
  *
7
- * Note that this function uses `fs.promises.readFile` and `fs.promises.opendir` without options within
8
- * custom recursion, instead of `fs.promises.readdir` with `{ withFileTypes: true }.
9
8
  * It also normalizes paths to use forward slashes.
10
- * Please report any issues if you encounter problems related to this behavior.
11
9
  *
12
10
  * @param options Scan options.
13
11
  * @returns A promise that resolves to a {@link MatcherContext} containing the scan results.
@@ -16,5 +14,19 @@ import { scan as browserScan } from "./browser_scan.js";
16
14
  */
17
15
  export function scan(options) {
18
16
  const { cwd = process.cwd(), fs = nodefs } = options;
19
- return browserScan({ fs, cwd, ...options });
17
+ return browserScan({ cwd, fs, ...options });
18
+ }
19
+ /**
20
+ * Scan the directory for included files based on the provided targets.
21
+ *
22
+ * It also normalizes paths to use forward slashes.
23
+ *
24
+ * @param options Scan options.
25
+ * @param cb Callback function.
26
+ *
27
+ * @since 0.11.0
28
+ */
29
+ export function scanCb(options, cb) {
30
+ const { cwd = process.cwd(), fs = nodefs } = options;
31
+ browserScanCb({ cwd, fs, ...options }, cb);
20
32
  }
@@ -0,0 +1,16 @@
1
+ import type { MatcherContext } from "./patterns/matcherContext.js";
2
+ import type { ScanOptions, FsAdapter } from "./types.js";
3
+ /**
4
+ * Scan the directory for included files based on the provided targets.
5
+ *
6
+ * It also normalizes paths to use forward slashes.
7
+ *
8
+ * @param options Scan options.
9
+ * @param cb Callback function.
10
+ *
11
+ * @since 0.11.0
12
+ */
13
+ export declare function scanCb(options: ScanOptions & {
14
+ fs: FsAdapter;
15
+ cwd: string;
16
+ }, cb: (err: Error | null, ctx: MatcherContext) => void): void;
package/out/scanCb.js ADDED
@@ -0,0 +1,73 @@
1
+ import { scanParallel } from "./scanParallel.js";
2
+ import { unixify } from "./unixify.js";
3
+ import { walkPatchResult, walkPatchTotal, propagateTotals } from "./walk.js";
4
+ /**
5
+ * Scan the directory for included files based on the provided targets.
6
+ *
7
+ * It also normalizes paths to use forward slashes.
8
+ *
9
+ * @param options Scan options.
10
+ * @param cb Callback function.
11
+ *
12
+ * @since 0.11.0
13
+ */
14
+ export function scanCb(options, cb) {
15
+ const { target, cwd, within = ".", invert = false, depth: maxDepth = Infinity, signal = null, fastDepth = false, fastInternal = false, fs, } = options;
16
+ if (maxDepth < 0) {
17
+ cb(new TypeError("Depth must be a non-negative integer"), null);
18
+ return;
19
+ }
20
+ const ctx = {
21
+ external: new Map(),
22
+ failed: [],
23
+ paths: new Map(),
24
+ total: new Map([[".", { totalDirs: 0, totalFiles: 0, totalMatchedFiles: 0 }]]),
25
+ };
26
+ const normalCwd = unixify(cwd);
27
+ const scanOptions = {
28
+ cwd: normalCwd,
29
+ depth: maxDepth,
30
+ fastDepth,
31
+ fastInternal,
32
+ fs,
33
+ invert,
34
+ signal,
35
+ target,
36
+ within,
37
+ };
38
+ const startScan = () => {
39
+ scanParallel({
40
+ external: ctx.external,
41
+ failed: ctx.failed,
42
+ onResult: (result) => {
43
+ if ("dir" in result) {
44
+ walkPatchTotal(ctx, scanOptions.depth, result);
45
+ }
46
+ else {
47
+ walkPatchResult(ctx, result);
48
+ }
49
+ },
50
+ scanOptions,
51
+ within,
52
+ }, (err) => {
53
+ if (err) {
54
+ cb(err, null);
55
+ return;
56
+ }
57
+ propagateTotals(ctx.total);
58
+ cb(null, ctx);
59
+ });
60
+ };
61
+ if (target.init) {
62
+ target.init({ cwd: normalCwd, fs, signal, target }, (err) => {
63
+ if (err) {
64
+ cb(err, null);
65
+ return;
66
+ }
67
+ startScan();
68
+ });
69
+ }
70
+ else {
71
+ startScan();
72
+ }
73
+ }
@@ -0,0 +1,18 @@
1
+ import type { MatcherStream } from "./patterns/matcherStream.js";
2
+ import type { Resource, InvalidSource } from "./patterns/resource.js";
3
+ import type { ScanOptions } from "./types.js";
4
+ import { type WalkResult, type WalkTotal } from "./walk.js";
5
+ export interface ScanParallelOptions {
6
+ scanOptions: Required<ScanOptions>;
7
+ within: string;
8
+ stream?: MatcherStream;
9
+ external: Map<string, Resource>;
10
+ failed?: InvalidSource[];
11
+ onResult?: (result: WalkResult | WalkTotal) => void;
12
+ }
13
+ /**
14
+ * Executes a parallel directory scan.
15
+ *
16
+ * @since 0.11.0
17
+ */
18
+ export declare function scanParallel(options: ScanParallelOptions, cb: (err: Error | null, results: WalkResult[] | null) => void): void;
@@ -0,0 +1,146 @@
1
+ import { resolveSources } from "./patterns/resolveSources.js";
2
+ import { join, unixify } from "./unixify.js";
3
+ import { walkIncludes } from "./walk.js";
4
+ /**
5
+ * Executes a parallel directory scan.
6
+ *
7
+ * @since 0.11.0
8
+ */
9
+ export function scanParallel(options, cb) {
10
+ const { scanOptions, stream, external, failed, onResult } = options;
11
+ scanOptions.cwd = unixify(scanOptions.cwd);
12
+ let { within } = options;
13
+ if (within.startsWith("./"))
14
+ within = within.slice(2);
15
+ const results = onResult ? null : [];
16
+ let activeTasks = 0;
17
+ let errorOccurred = null;
18
+ function walk(relPath, depth, resource, lowerRelPath) {
19
+ if (errorOccurred)
20
+ return;
21
+ activeTasks++;
22
+ scanOptions.fs.readdir(join(scanOptions.cwd, relPath), { withFileTypes: true }, (err, entries) => {
23
+ if (err) {
24
+ handleError(err);
25
+ return;
26
+ }
27
+ resolveSources({ ...scanOptions, dir: relPath, entries, external, resource }, (err, res) => {
28
+ if (err) {
29
+ handleError(err);
30
+ return;
31
+ }
32
+ if (res && "error" in res && res.error) {
33
+ if (failed) {
34
+ failed.push(res);
35
+ }
36
+ else {
37
+ handleError(res.error);
38
+ return;
39
+ }
40
+ }
41
+ const len = entries.length;
42
+ const prefix = relPath === "." || relPath === "" ? "" : relPath + "/";
43
+ const lowerPrefix = lowerRelPath
44
+ ? lowerRelPath + "/"
45
+ : prefix
46
+ ? prefix.toLowerCase()
47
+ : "";
48
+ let pendingResults = len;
49
+ let dirFiles = 0;
50
+ let dirMatched = 0;
51
+ let dirDirs = 0;
52
+ if (len === 0) {
53
+ if (onResult) {
54
+ onResult({
55
+ depth,
56
+ dir: relPath,
57
+ dirs: 0,
58
+ files: 0,
59
+ ignored: false,
60
+ matched: 0,
61
+ type: "total",
62
+ });
63
+ }
64
+ }
65
+ for (let i = 0; i < len; i++) {
66
+ const entry = entries[i];
67
+ activeTasks++;
68
+ const name = entry.name;
69
+ const currentRelPath = prefix + name;
70
+ const currentLowerRelPath = lowerPrefix + name.toLowerCase();
71
+ walkIncludes({
72
+ depth,
73
+ entry,
74
+ lowerRelPath: currentLowerRelPath,
75
+ parentPath: relPath,
76
+ relPath: currentRelPath,
77
+ resource: res,
78
+ scanOptions,
79
+ stream,
80
+ }, (err, self) => {
81
+ if (err) {
82
+ handleError(err);
83
+ return;
84
+ }
85
+ if (self && self.match) {
86
+ if (self.isDir) {
87
+ dirDirs++;
88
+ }
89
+ else {
90
+ dirFiles++;
91
+ if (!self.match.ignored)
92
+ dirMatched++;
93
+ }
94
+ if (onResult) {
95
+ onResult(self);
96
+ }
97
+ else {
98
+ results.push(self);
99
+ }
100
+ if (entry.isDirectory() && self.next === 0) {
101
+ walk(currentRelPath, depth + 1, res, currentLowerRelPath);
102
+ }
103
+ }
104
+ pendingResults--;
105
+ if (pendingResults === 0) {
106
+ if (onResult) {
107
+ onResult({
108
+ depth,
109
+ dir: relPath,
110
+ dirs: dirDirs,
111
+ files: dirFiles,
112
+ ignored: false,
113
+ matched: dirMatched,
114
+ type: "total",
115
+ });
116
+ }
117
+ }
118
+ taskDone();
119
+ });
120
+ }
121
+ taskDone();
122
+ });
123
+ });
124
+ }
125
+ function handleError(err) {
126
+ if (!errorOccurred) {
127
+ errorOccurred = err;
128
+ cb(err, null);
129
+ }
130
+ }
131
+ function taskDone() {
132
+ activeTasks--;
133
+ if (activeTasks === 0 && !errorOccurred) {
134
+ cb(null, results);
135
+ }
136
+ }
137
+ let initialDepth = 0;
138
+ if (within !== "." && within !== "") {
139
+ const len = within.length;
140
+ for (let i = 0; i < len; i++) {
141
+ if (within.charCodeAt(i) === 47)
142
+ initialDepth++;
143
+ }
144
+ }
145
+ walk(within, initialDepth, undefined, within === "." || within === "" ? "" : within.toLowerCase());
146
+ }