Skip to content

Commit 13e391b

Browse files
committed
feat: support watcher
1 parent 9c6e747 commit 13e391b

File tree

7 files changed

+304
-36
lines changed

7 files changed

+304
-36
lines changed

docs/src/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Adds two numbers together.
3+
*
4+
* @example
5+
*
6+
* ```js
7+
* add(1, 2); // 3
8+
* ```
9+
*/
10+
export function add(a: number, b: number) {
11+
return a + b;
12+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"test:types": "tsc --noEmit --skipLibCheck"
3434
},
3535
"dependencies": {
36+
"@parcel/watcher": "^2.4.0",
3637
"c12": "^1.7.0",
3738
"citty": "^0.1.5",
3839
"consola": "^3.2.3",

pnpm-lock.yaml

Lines changed: 145 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/automd.ts

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import { existsSync, promises as fsp } from "node:fs";
22
import { resolve, relative } from "pathe";
3+
import type { SubscribeCallback } from "@parcel/watcher";
34
import type { Config, ResolvedConfig } from "./config";
4-
import { TransformResult, transform } from "./transform";
5+
import { type TransformResult, transform } from "./transform";
56
import { loadConfig } from "./config";
67

78
export interface AutomdResult extends TransformResult {
8-
_config: ResolvedConfig;
99
input: string;
1010
output: string;
1111
}
1212

13-
export async function automd(_config: Config = {}): Promise<AutomdResult[]> {
13+
export async function automd(
14+
_config: Config = {},
15+
): Promise<{ results: AutomdResult[]; _config: ResolvedConfig; time: number }> {
1416
const config = await loadConfig(_config.dir, _config);
1517

1618
let inputFiles = config.input;
@@ -20,40 +22,97 @@ export async function automd(_config: Config = {}): Promise<AutomdResult[]> {
2022
cwd: config.dir,
2123
absolute: false,
2224
onlyFiles: true,
23-
ignore: ["node_modules", "dist", ".*", ...(config.ignore || [])],
25+
ignore: config.ignore,
2426
});
2527
} else {
2628
inputFiles = inputFiles
2729
.map((i) => resolve(config.dir, i))
2830
.filter((i) => existsSync(i))
2931
.map((i) => relative(config.dir, i));
3032
}
33+
const multiFiles = inputFiles.length > 1;
3134

32-
return Promise.all(
33-
inputFiles.map((i) => _automd(i, config, inputFiles.length > 1)),
35+
const cache: ResultCache = new Map();
36+
37+
const start = performance.now();
38+
const results = await Promise.all(
39+
inputFiles.map((i) => _automd(i, config, multiFiles, cache)),
3440
);
41+
const time = Math.round((performance.now() - start) * 1000) / 1000;
42+
43+
if (config.watch) {
44+
await _watch(inputFiles, config, multiFiles, cache);
45+
}
46+
47+
return {
48+
_config: config,
49+
time,
50+
results,
51+
};
3552
}
3653

37-
export async function _automd(
54+
// -- internal --
55+
56+
type ResultCache = Map<string, AutomdResult>;
57+
58+
async function _automd(
3859
relativeInput: string,
3960
config: ResolvedConfig,
40-
multi: boolean,
61+
multiFiles: boolean,
62+
cache: ResultCache,
4163
): Promise<AutomdResult> {
4264
const input = resolve(config.dir, relativeInput);
4365
const contents = await fsp.readFile(input, "utf8");
4466

45-
const result = await transform(contents, config);
67+
const cachedResult = await cache.get(input);
68+
if (cachedResult?.contents === contents) {
69+
return cachedResult;
70+
}
71+
72+
const transformResult = await transform(contents, config);
4673

47-
const output = multi
74+
const output = multiFiles
4875
? resolve(config.dir, config.output || ".", relativeInput)
4976
: resolve(config.dir, config.output || relativeInput);
5077

51-
await fsp.writeFile(output, result.contents, "utf8");
78+
await fsp.writeFile(output, transformResult.contents, "utf8");
5279

53-
return {
54-
_config: config,
80+
const result: AutomdResult = {
5581
input,
5682
output,
57-
...result,
83+
...transformResult,
84+
};
85+
cache.set(input, result);
86+
return result;
87+
}
88+
89+
async function _watch(
90+
inputFiles: string[],
91+
config: ResolvedConfig,
92+
multiFiles: boolean,
93+
cache: ResultCache,
94+
) {
95+
const watcher = await import("@parcel/watcher");
96+
97+
const watchCb: SubscribeCallback = async (_err, events) => {
98+
const filesToUpdate = events
99+
.map((e) => relative(config.dir, e.path))
100+
.filter((p) => inputFiles.includes(p));
101+
const start = performance.now();
102+
const results = await Promise.all(
103+
filesToUpdate.map((f) => _automd(f, config, multiFiles, cache)),
104+
);
105+
const time = performance.now() - start;
106+
if (config.onWatch) {
107+
config.onWatch({ results, time });
108+
}
58109
};
110+
111+
const subscription = await watcher.subscribe(config.dir, watchCb, {
112+
ignore: config.ignore,
113+
});
114+
115+
process.on("SIGINT", () => {
116+
subscription.unsubscribe();
117+
});
59118
}

0 commit comments

Comments
 (0)