view-ignored 0.10.0 → 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 +118 -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 +23 -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 +158 -75
  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 +48 -19
  27. package/out/patterns/patternList.d.ts +12 -6
  28. package/out/patterns/patternList.js +8 -4
  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 +63 -9
  34. package/out/patterns/rule.js +101 -66
  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 +43 -4
  63. package/out/walk.js +146 -84
  64. package/package.json +27 -23
  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 -22
package/out/walk.d.ts CHANGED
@@ -1,12 +1,51 @@
1
1
  import type { Dirent } from "node:fs";
2
- import type { MatcherContext } from "./patterns/matcherContext.js";
2
+ import type { MatcherContext, Total } from "./patterns/matcherContext.js";
3
3
  import type { MatcherStream } from "./patterns/matcherStream.js";
4
+ import type { Resource } from "./patterns/resource.js";
4
5
  import type { ScanOptions } from "./types.js";
6
+ import { type RuleMatch } from "./patterns/rule.js";
5
7
  export type WalkOptions = {
6
- path: string;
8
+ relPath: string;
9
+ lowerRelPath?: string;
10
+ parentPath: string;
7
11
  entry: Dirent;
8
- ctx: MatcherContext;
12
+ resource: Resource;
9
13
  stream: MatcherStream | undefined;
10
14
  scanOptions: Required<ScanOptions>;
15
+ depth: number;
16
+ };
17
+ export type WalkResult = {
18
+ path: string;
19
+ parentPath: string;
20
+ match: RuleMatch;
21
+ includeParent: boolean;
22
+ tooDeep: boolean;
23
+ next: 0 | 1;
24
+ depth: number;
25
+ isDir: boolean;
26
+ };
27
+ export type WalkTotal = {
28
+ type?: "total";
29
+ dir: string;
30
+ files: number;
31
+ matched: number;
32
+ dirs: number;
33
+ depth: number;
34
+ ignored: boolean;
11
35
  };
12
- export declare function walkIncludes(options: WalkOptions): Promise<0 | 1 | 2>;
36
+ /**
37
+ * @since 0.11.0
38
+ */
39
+ export declare function walkIncludes(options: WalkOptions, cb: (err: Error | null, result: WalkResult) => void): void;
40
+ /**
41
+ * Patches the {@link MatcherContext} with the given result.
42
+ */
43
+ export declare function walkPatchResult(ctx: MatcherContext, r: WalkResult): void;
44
+ /**
45
+ * Patches the {@link MatcherContext} with the given total.
46
+ */
47
+ export declare function walkPatchTotal(ctx: MatcherContext, maxDepth: number, t: WalkTotal): void;
48
+ /**
49
+ * Propagates totals from child directories to their parents.
50
+ */
51
+ export declare function propagateTotals(total: Map<string, Total>): void;
package/out/walk.js CHANGED
@@ -1,104 +1,166 @@
1
- import { getDepth } from "./getDepth.js";
2
- export async function walkIncludes(options) {
3
- const { entry, ctx, stream, scanOptions, path } = options;
4
- const { fs, target, cwd, depth: maxDepth, invert, signal, fastDepth, fastInternal } = scanOptions;
5
- signal?.throwIfAborted();
1
+ import { isRuleMatchInvalid } from "./patterns/rule.js";
2
+ /**
3
+ * @since 0.11.0
4
+ */
5
+ export function walkIncludes(options, cb) {
6
+ const { entry, stream, scanOptions, relPath: path, lowerRelPath, parentPath, resource, depth, } = options;
7
+ const { target, depth: maxDepth, invert, fastDepth, fastInternal, fs, cwd, signal } = scanOptions;
6
8
  const isDir = entry.isDirectory();
7
- let direntPath;
8
- if (isDir) {
9
- direntPath = path + "/";
10
- ctx.totalDirs++;
11
- }
12
- else {
13
- direntPath = path;
14
- ctx.totalFiles++;
15
- }
16
- if (fastDepth) {
17
- const { depth, depthSlash } = getDepth(path, maxDepth);
18
- if (depth > maxDepth) {
19
- const failedPrev = ctx.failed.length;
20
- let match = await target.ignores({ fs, cwd, entry: path, ctx, signal, target });
21
- if (invert) {
9
+ const direntPath = isDir ? path + "/" : path;
10
+ const lowerEntry = lowerRelPath || path.toLowerCase();
11
+ const testOptions = {
12
+ cwd,
13
+ entry: path,
14
+ fs,
15
+ lowerEntry,
16
+ parentPath,
17
+ resource,
18
+ signal,
19
+ target,
20
+ };
21
+ if (fastDepth && depth > maxDepth) {
22
+ return target.ignores(testOptions, (err, match) => {
23
+ if (err)
24
+ return cb(err, null);
25
+ if (invert)
22
26
  match.ignored = !match.ignored;
23
- }
24
- if (failedPrev < ctx.failed.length) {
27
+ const result = {
28
+ depth,
29
+ includeParent: false,
30
+ isDir,
31
+ match,
32
+ next: 0,
33
+ parentPath,
34
+ path: direntPath,
35
+ tooDeep: true,
36
+ };
37
+ if (isRuleMatchInvalid(match)) {
25
38
  if (stream) {
26
- stream.emit("dirent", { dirent: entry, match, path: direntPath, ctx });
39
+ stream.dispatchEvent(new CustomEvent("dirent", { detail: { dirent: entry, match, path: direntPath } }));
27
40
  }
28
- return 2;
41
+ return cb(null, result);
29
42
  }
30
43
  if (match.ignored) {
31
- if (isDir && fastInternal && match.kind === "internal") {
32
- return 1;
33
- }
34
- return 0;
44
+ if (stream)
45
+ stream.dispatchEvent(new CustomEvent("dirent", { detail: { dirent: entry, match, path: direntPath } }));
46
+ if (isDir && fastInternal)
47
+ result.next = 1;
48
+ return cb(null, result);
49
+ }
50
+ result.next = isDir ? 0 : 1;
51
+ cb(null, result);
52
+ });
53
+ }
54
+ target.ignores(testOptions, (err, match) => {
55
+ if (err)
56
+ return cb(err, null);
57
+ if (invert)
58
+ match.ignored = !match.ignored;
59
+ const result = {
60
+ depth,
61
+ includeParent: false,
62
+ isDir,
63
+ match,
64
+ next: 0,
65
+ parentPath,
66
+ path: direntPath,
67
+ tooDeep: false,
68
+ };
69
+ if (isRuleMatchInvalid(match)) {
70
+ if (stream)
71
+ stream.dispatchEvent(new CustomEvent("dirent", { detail: { dirent: entry, match, path: direntPath } }));
72
+ return cb(null, result);
73
+ }
74
+ if (match.ignored) {
75
+ if (stream)
76
+ stream.dispatchEvent(new CustomEvent("dirent", { detail: { dirent: entry, match, path: direntPath } }));
77
+ if (isDir && fastInternal)
78
+ result.next = 1;
79
+ return cb(null, result);
80
+ }
81
+ if (isDir) {
82
+ if (depth <= maxDepth) {
83
+ if (stream)
84
+ stream.dispatchEvent(new CustomEvent("dirent", { detail: { dirent: entry, match, path: direntPath } }));
35
85
  }
36
- if (isDir) {
37
- // ctx.totalMatchedDirs++;
38
- // ctx.depthPaths.set(path, (ctx.depthPaths.get(path) ?? 0) + 1);
39
- return 0;
86
+ else {
87
+ result.tooDeep = true;
40
88
  }
41
- ctx.totalMatchedFiles++;
42
- const dir = path.substring(0, depthSlash);
43
- ctx.depthPaths.set(dir, (ctx.depthPaths.get(dir) ?? 0) + 1);
44
- return 1;
89
+ return cb(null, result);
45
90
  }
46
- }
47
- const failedPrev = ctx.failed.length;
48
- let match = await target.ignores({ fs, cwd, entry: path, ctx, signal, target });
49
- if (invert) {
50
- match.ignored = !match.ignored;
51
- }
52
- if (failedPrev < ctx.failed.length) {
53
- if (stream) {
54
- stream.emit("dirent", { dirent: entry, match, path: direntPath, ctx });
91
+ if (depth > maxDepth) {
92
+ result.tooDeep = true;
93
+ return cb(null, result);
55
94
  }
56
- return 2;
57
- }
58
- if (match.ignored) {
95
+ const lastSlash = path.lastIndexOf("/");
96
+ if (lastSlash >= 0)
97
+ result.includeParent = true;
59
98
  if (stream) {
60
- stream.emit("dirent", { dirent: entry, match, path: direntPath, ctx });
61
- }
62
- if (isDir && fastInternal && match.kind === "internal") {
63
- return 1;
99
+ if (result.includeParent)
100
+ stream.dispatchEvent(new CustomEvent("dirent", { detail: { dirent: entry, match, path: parentPath + "/" } }));
101
+ stream.dispatchEvent(new CustomEvent("dirent", { detail: { dirent: entry, match, path: direntPath } }));
64
102
  }
65
- return 0;
66
- }
103
+ cb(null, result);
104
+ });
105
+ }
106
+ /**
107
+ * Patches the {@link MatcherContext} with the given result.
108
+ */
109
+ export function walkPatchResult(ctx, r) {
110
+ const { path, parentPath, match, isDir, tooDeep, includeParent } = r;
67
111
  if (isDir) {
68
- // ctx.totalMatchedDirs++;
69
- // ctx.depthPaths.set(path, (ctx.depthPaths.get(path) ?? 0) + 1);
70
- const { depth } = getDepth(path, maxDepth);
71
- if (depth <= maxDepth) {
72
- ctx.paths.set(direntPath, match);
73
- if (stream) {
74
- stream.emit("dirent", { dirent: entry, match, path: direntPath, ctx });
75
- }
112
+ if (!match.ignored && !tooDeep)
113
+ ctx.paths.set(path, match);
114
+ }
115
+ else {
116
+ if (!match.ignored) {
117
+ if (!tooDeep)
118
+ ctx.paths.set(path, match);
76
119
  }
77
- return 0;
78
120
  }
79
- ctx.totalMatchedFiles++;
80
- const { depth, depthSlash } = getDepth(path, maxDepth);
81
- if (depth > maxDepth) {
82
- const dir = path.substring(0, depthSlash);
83
- ctx.depthPaths.set(dir, (ctx.depthPaths.get(dir) ?? 0) + 1);
84
- return 0;
121
+ if (includeParent && !match.ignored)
122
+ if (!ctx.paths.has(parentPath + "/"))
123
+ ctx.paths.set(parentPath + "/", match);
124
+ }
125
+ /**
126
+ * Patches the {@link MatcherContext} with the given total.
127
+ */
128
+ export function walkPatchTotal(ctx, maxDepth, t) {
129
+ const { dir, files, matched, dirs, ignored } = t;
130
+ const dirTotal = ctx.total.get(dir);
131
+ if (dirTotal) {
132
+ dirTotal.totalFiles += files;
133
+ dirTotal.totalDirs += dirs;
134
+ dirTotal.totalMatchedFiles += matched;
85
135
  }
86
- if (depth <= maxDepth) {
87
- const lastSlash = path.lastIndexOf("/");
88
- if (lastSlash >= 0) {
89
- const dir = path.substring(0, lastSlash) + "/";
90
- const dirMatch = ctx.paths.get(dir);
91
- if (dirMatch === undefined || dirMatch.ignored) {
92
- ctx.paths.set(dir, match);
93
- if (stream) {
94
- stream.emit("dirent", { dirent: entry, match, path: dir, ctx });
95
- }
96
- }
136
+ else if (t.depth <= maxDepth && !ignored) {
137
+ ctx.total.set(dir, { totalDirs: dirs, totalFiles: files, totalMatchedFiles: matched });
138
+ }
139
+ }
140
+ /**
141
+ * Propagates totals from child directories to their parents.
142
+ */
143
+ export function propagateTotals(total) {
144
+ const dirs = Array.from(total.keys()).sort((a, b) => b.length - a.length);
145
+ for (let i = 0, len = dirs.length; i < len; i++) {
146
+ const dir = dirs[i];
147
+ if (dir === "." || dir === "/")
148
+ continue;
149
+ const dirTotal = total.get(dir);
150
+ const lastSlash = dir.lastIndexOf("/");
151
+ const parent = lastSlash === -1 ? "." : dir.slice(0, lastSlash) || "/";
152
+ const parentTotal = total.get(parent);
153
+ if (parentTotal) {
154
+ parentTotal.totalFiles += dirTotal.totalFiles;
155
+ parentTotal.totalDirs += dirTotal.totalDirs;
156
+ parentTotal.totalMatchedFiles += dirTotal.totalMatchedFiles;
97
157
  }
98
- ctx.paths.set(path, match);
99
- if (stream) {
100
- stream.emit("dirent", { dirent: entry, match, path: direntPath, ctx });
158
+ else {
159
+ total.set(parent, {
160
+ totalDirs: dirTotal.totalDirs,
161
+ totalFiles: dirTotal.totalFiles,
162
+ totalMatchedFiles: dirTotal.totalMatchedFiles,
163
+ });
101
164
  }
102
165
  }
103
- return 0;
104
166
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "view-ignored",
3
- "version": "0.10.0",
4
- "description": "Retrieve list of files ignored/included by Git, NPM, Yarn, JSR, VSCE or other tools.",
3
+ "version": "0.11.0",
4
+ "description": "Retrieve list of files ignored/included by Git, NPM, Yarn, JSR, Deno, Bun, VSCode extension CLI and other tools.",
5
5
  "keywords": [
6
6
  ".gitignore",
7
7
  ".npmignore",
@@ -77,9 +77,12 @@
77
77
  },
78
78
  "scripts": {
79
79
  "prerelease": "bun run test && bun run prod && bun run lint && bun run fmt --check && bun publint --pack bun --strict",
80
- "cpu": "bun run cpu:igw; bun run cpu:me",
81
- "cpu:igw": "bun run --expose-gc --cpu-prof --cpu-prof-md --cpu-prof-name CPU.igw scripts/ignoreWalk.js",
82
- "cpu:me": "bun run --expose-gc --cpu-prof --cpu-prof-md --cpu-prof-name CPU.me scripts/scan.js --fastInternal",
80
+ "heap": "bun scripts/scanHeap.js --snapshot",
81
+ "heap:node": "node scripts/scanHeap.js --snapshot",
82
+ "cpu": "bun run --expose-gc --cpu-prof --cpu-prof-md --cpu-prof-name CPU.me scripts/scan.js --fastInternal",
83
+ "cpu:node": "node --expose-gc --cpu-prof --cpu-prof-name CPU.me.node.cpuprofile scripts/scan.js --fastInternal",
84
+ "bench": "bun run --expose-gc benchmarks/git.js && bun run --expose-gc benchmarks/npm.js",
85
+ "bench:node": "node --expose-gc benchmarks/git.js && node --expose-gc benchmarks/npm.js",
83
86
  "test": "bun test src",
84
87
  "test:patterns": "bun test src/patterns",
85
88
  "test:targets": "bun test src/targets",
@@ -89,31 +92,32 @@
89
92
  "test:self:npm": "bun test src/testSelfNPM.test.ts",
90
93
  "lint": "bun run oxlint --type-aware",
91
94
  "fmt": "bun run oxfmt",
92
- "check": "bun tsgo -p . --noEmit",
93
- "prod": "rm -rf out && tsgo -p tsconfig.prod.json",
94
- "release:major": "bun run release-it --increment=major",
95
- "release:minor": "bun run release-it --increment=minor",
96
- "release:patch": "bun run release-it --increment=patch"
95
+ "check": "bun tsgo -p src --noEmit",
96
+ "dev": "bun tsgo -p src",
97
+ "prod": "rm -rf out && bun tsgo -p src/tsconfig.prod.json",
98
+ "release:major": "bun run --bun release-it --increment=major",
99
+ "release:minor": "bun run --bun release-it --increment=minor",
100
+ "release:patch": "bun run --bun release-it --increment=patch"
97
101
  },
98
102
  "dependencies": {
99
- "arktype": "^2.1.29",
100
- "minimatch": "^10.2.2",
103
+ "micromatch": "^4.0.8",
101
104
  "strip-json-comments": "^5.0.3"
102
105
  },
103
106
  "devDependencies": {
104
- "@release-it/keep-a-changelog": "^7.0.1",
105
- "@types/bun": "^1.3.9",
107
+ "@release-it/keep-a-changelog": "latest",
108
+ "@types/bun": "latest",
106
109
  "@types/ignore-walk": "^4.0.3",
110
+ "@types/micromatch": "^4.0.10",
107
111
  "@types/node": "^18.19.130",
108
- "@typescript/native-preview": "^7.0.0-dev.20260223.1",
109
- "ignore-walk": "^8.0.0",
110
- "memfs": "^4.56.10",
111
- "mitata": "^1.0.34",
112
- "oxfmt": "^0.35.0",
113
- "oxlint": "^1.50.0",
114
- "oxlint-tsgolint": "^0.14.2",
115
- "publint": "^0.3.17",
116
- "release-it": "^19.2.4"
112
+ "@typescript/native-preview": "latest",
113
+ "ignore-walk": "latest",
114
+ "memfs": "latest",
115
+ "mitata": "latest",
116
+ "oxfmt": "latest",
117
+ "oxlint": "latest",
118
+ "oxlint-tsgolint": "latest",
119
+ "publint": "latest",
120
+ "release-it": "latest"
117
121
  },
118
122
  "engines": {
119
123
  "node": ">=18"
package/out/getDepth.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export declare function getDepth(path: string, maxDepth: number): {
2
- depth: number;
3
- depthSlash: number;
4
- };
package/out/getDepth.js DELETED
@@ -1,21 +0,0 @@
1
- export function getDepth(path, maxDepth) {
2
- if (path.endsWith("/")) {
3
- path = path.substring(0, path.length - 1);
4
- }
5
- const result = {
6
- depth: 0,
7
- depthSlash: -1,
8
- };
9
- let i = -1;
10
- for (const c of path) {
11
- i++;
12
- if (c !== "/") {
13
- continue;
14
- }
15
- if (result.depth === maxDepth) {
16
- result.depthSlash = i;
17
- }
18
- result.depth++;
19
- }
20
- return result;
21
- }
package/out/opendir.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import type { Dirent, PathLike } from "node:fs";
2
- import type { FsAdapter } from "./types.js";
3
- export declare function opendir(fs: FsAdapter, path: PathLike, cb: (entry: Dirent, from: string) => Promise<0 | 1 | 2>): Promise<void | 2>;
package/out/opendir.js DELETED
@@ -1,22 +0,0 @@
1
- export async function opendir(fs, path, cb) {
2
- const dir = await fs.promises.opendir(path);
3
- const tasks = [];
4
- for await (const entry of dir) {
5
- const from = path + "/" + entry.name;
6
- const task = (async () => {
7
- const r = await cb(entry, from);
8
- if (r === 2)
9
- return 2;
10
- if (r === 1)
11
- return;
12
- if (entry.isDirectory()) {
13
- return await opendir(fs, from, cb);
14
- }
15
- })();
16
- tasks.push(task);
17
- }
18
- const results = await Promise.all(tasks);
19
- if (results.includes(2)) {
20
- return 2;
21
- }
22
- }