Skip to content
This repository was archived by the owner on Mar 5, 2023. It is now read-only.

Commit aa1ffab

Browse files
authored
Merge pull request #59 from FredyC/multiple-patterns
Support multiple input patterns
2 parents 1a09a31 + 0fe4c14 commit aa1ffab

File tree

7 files changed

+117
-130
lines changed

7 files changed

+117
-130
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'xstate-codegen': minor
3+
---
4+
5+
CLI now supports multiple input patterns. There are some minor changes in output of logs, but nothing too serious. Also the check if some files are matching the given patterns was lost in the process.

.changeset/cool-candles-share.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"xstate-codegen": minor
3+
---
4+
5+
Added support multiple for passing multiple input patterns.
6+
7+
Fixed a bug where new files added while watching would not be picked up.

packages/xstate-compiled/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
"@babel/core": "^7.10.4",
1010
"@babel/helper-split-export-declaration": "^7.11.0",
1111
"@babel/parser": "^7.10.4",
12-
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
1312
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
13+
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
1414
"@babel/plugin-transform-typescript": "^7.10.4",
1515
"@rollup/plugin-babel": "^5.2.0",
1616
"@rollup/plugin-node-resolve": "^9.0.0",
1717
"babel-plugin-macros": "^2.8.0",
18+
"chokidar": "^3.4.3",
1819
"colors": "^1.4.0",
19-
"gaze": "^1.1.3",
2020
"glob": "^7.1.6",
2121
"handlebars": "^4.7.6",
2222
"handlebars-helpers": "^0.10.0",
@@ -26,7 +26,6 @@
2626
"xstate": "^4.12.0"
2727
},
2828
"devDependencies": {
29-
"@types/rimraf": "^3.0.0",
3029
"@changesets/cli": "^2.9.2",
3130
"@types/babel-plugin-macros": "^2.8.2",
3231
"@types/babel__core": "^7.1.9",
@@ -35,9 +34,10 @@
3534
"@types/handlebars-helpers": "^0.5.2",
3635
"@types/minimist": "^1.2.0",
3736
"@types/node": "^14.0.14",
37+
"@types/rimraf": "^3.0.0",
3838
"@xstate/react": "^0.8.1",
39-
"typescript": "^3.9.7",
40-
"nodemon": "2.0.4"
39+
"nodemon": "2.0.4",
40+
"typescript": "^3.9.7"
4141
},
4242
"scripts": {
4343
"local-link": "yarn unlink && npm run build && npm run chmod:index && yarn link",
Lines changed: 75 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,107 @@
11
#!/usr/bin/env node
22

3-
import gaze from 'gaze';
3+
import chokidar from 'chokidar';
44
import fs from 'fs';
55
import path from 'path';
66
import minimist from 'minimist';
77
import { introspectMachine } from './introspectMachine';
88
import { extractMachines } from './extractMachines';
99
import { printToFile, printJsFiles } from './printToFile';
1010

11-
const { _: arrayArgs, ...objectArgs } = minimist(process.argv.slice(2));
11+
const { _: patterns, ...objectArgs } = minimist(process.argv.slice(2));
12+
const onlyOnce = objectArgs.once;
1213

13-
const [, , pattern] = process.argv;
14-
15-
type RecordOfArrays = Record<string, string[]>;
16-
17-
const flattenRecords = (
18-
filesAsRecord: Record<string, RecordOfArrays | string[]> | string[],
19-
): string[] => {
20-
if (Array.isArray(filesAsRecord)) {
21-
return filesAsRecord;
22-
}
23-
return Object.values(filesAsRecord).reduce(
24-
(array, paths) => array.concat(flattenRecords(paths)),
25-
[] as any,
26-
) as string[];
27-
};
28-
29-
if (!pattern) {
30-
console.log('You must pass a glob, for instance "**/src/**.machine.ts"');
14+
if (patterns.length === 0) {
15+
console.log(
16+
'You must pass at least one glob, for instance "**/src/**.machine.ts"',
17+
);
3118
process.exit(1);
3219
}
3320

34-
const toRelative = (filePath: string) => path.relative(process.cwd(), filePath);
35-
3621
const typedSuffix = /\.typed\.(js|ts|tsx|jsx)$/;
37-
3822
const tsExtension = /\.(ts|tsx|js|jsx)$/;
23+
function isValidFile(filePath: string) {
24+
return !typedSuffix.test(filePath) && tsExtension.test(filePath);
25+
}
3926

40-
let fileCache: Record<
27+
const fileCache: Record<
4128
string,
4229
ReturnType<typeof introspectMachine> & { id: string }
4330
> = {};
4431

45-
gaze(pattern, {}, async function(err, watcher) {
46-
if (err) {
47-
console.log(err);
48-
process.exit(1);
49-
}
32+
printJsFiles();
33+
if (!onlyOnce) {
34+
console.clear();
35+
}
5036

51-
const filesAsRecord: Record<string, string[]> = watcher.watched() as any;
37+
const watcher = chokidar.watch(patterns, {
38+
persistent: !onlyOnce,
39+
});
5240

53-
const files = flattenRecords(filesAsRecord);
41+
watcher.on('error', (err) => {
42+
console.error(err);
43+
process.exit(1);
44+
});
5445

55-
const filteredFiles = files.filter((filePath) => {
56-
return !typedSuffix.test(filePath) && tsExtension.test(filePath);
57-
});
46+
const toRelative = (filePath: string) => path.relative(process.cwd(), filePath);
5847

59-
if (filteredFiles.length === 0) {
60-
console.log('No files found from that glob');
61-
process.exit(1);
48+
watcher.on('all', async (eventName, filePath) => {
49+
if (!isValidFile(filePath)) {
50+
return;
51+
}
52+
let message = '';
53+
if (eventName === 'add') {
54+
message += `Scanning File: `.cyan.bold;
55+
await addToCache(filePath);
56+
}
57+
if (eventName === 'change') {
58+
message += `File Changed: `.yellow.bold;
59+
await addToCache(filePath);
60+
}
61+
if (eventName === 'unlink') {
62+
message += `File Deleted: `.red.bold;
63+
removeFromCache(filePath);
64+
}
65+
if (message) {
66+
console.log(`${message} ${toRelative(filePath).gray}`);
6267
}
63-
64-
printJsFiles();
65-
console.clear();
66-
67-
const addToCache = async (filePath: string) => {
68-
let code: string = '';
69-
try {
70-
code = fs.readFileSync(filePath, 'utf8');
71-
} catch (e) {}
72-
if (!code) {
73-
console.log(`Could not read from path ${filePath}`);
74-
return;
75-
}
76-
if (!code.includes('@xstate/compiled')) {
77-
return;
78-
}
79-
const machines = await extractMachines(filePath);
80-
if (machines.length === 0) {
81-
return;
82-
}
83-
const { machine, id } = machines[0];
84-
fileCache[filePath] = { ...introspectMachine(machine), id };
85-
};
86-
87-
await filteredFiles.reduce(async (promise, filePath) => {
88-
await promise;
89-
try {
90-
console.log(`Scanning File: `.cyan.bold + toRelative(filePath).gray);
91-
await addToCache(filePath);
92-
} catch (e) {
93-
console.log(e);
94-
if (objectArgs.once) {
95-
console.log('Could not complete due to errors'.red.bold);
96-
// @ts-ignore
97-
this.close();
98-
process.exit(1);
99-
}
100-
}
101-
}, Promise.resolve());
102-
10368
printToFile(fileCache, objectArgs.outDir);
69+
});
10470

105-
if (objectArgs.once) {
71+
process.on('exit', () => {
72+
if (onlyOnce) {
73+
// little trick because `ready` doesn't work well to know the inital run is complete
10674
console.log('Completed!'.green.bold);
107-
// @ts-ignore
108-
this.close();
109-
process.exit(0);
11075
}
76+
});
11177

112-
// @ts-ignore
113-
this.on('changed', async (filePath) => {
114-
console.log(`File Changed: `.cyan.bold + toRelative(filePath).gray);
115-
await addToCache(filePath);
116-
printToFile(fileCache, objectArgs.outDir);
117-
});
118-
// @ts-ignore
119-
this.on('added', async (filePath) => {
120-
console.log(`File Added: `.green.bold + toRelative(filePath).gray);
121-
await addToCache(filePath);
122-
printToFile(fileCache, objectArgs.outDir);
123-
});
78+
watcher.on('ready', async () => {
79+
if (!onlyOnce) {
80+
patterns.forEach((pattern) => {
81+
console.log(`Watching for file changes in: `.cyan.bold + pattern);
82+
});
83+
}
84+
});
12485

125-
// @ts-ignore
126-
this.on('deleted', async (filePath) => {
127-
console.log(`File Deleted: `.red.bold + toRelative(filePath).gray);
128-
delete fileCache[filePath];
129-
printToFile(fileCache, objectArgs.outDir);
130-
});
86+
async function addToCache(filePath: string) {
87+
let code: string = '';
88+
try {
89+
code = fs.readFileSync(filePath, 'utf8');
90+
} catch (e) {}
91+
if (!code) {
92+
throw new Error(`Could not read from path ${filePath}`);
93+
}
94+
if (!code.includes('@xstate/compiled')) {
95+
return;
96+
}
97+
const machines = await extractMachines(filePath);
98+
if (machines.length === 0) {
99+
return;
100+
}
101+
const { machine, id } = machines[0];
102+
fileCache[filePath] = { ...introspectMachine(machine), id };
103+
}
131104

132-
console.log(`Watching for file changes in: `.cyan.bold + pattern.gray);
133-
});
105+
function removeFromCache(filePath: string) {
106+
delete fileCache[filePath];
107+
}

packages/xstate-compiled/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ execSync(
99
`cd examples && ${
1010
// If in CI, use node. If in local development, use ts-node
1111
process.env.CI ? 'node ../bin/index.js' : 'ts-node -T ../src/index.ts'
12-
} "*.machine.ts" --once`,
12+
} "*.machine.ts" "*Machine.ts" --once`,
1313
{
1414
stdio: 'inherit',
1515
},

yarn.lock

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,21 @@ chokidar@^3.2.2:
12121212
optionalDependencies:
12131213
fsevents "~2.1.2"
12141214

1215+
chokidar@^3.4.3:
1216+
version "3.4.3"
1217+
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b"
1218+
integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==
1219+
dependencies:
1220+
anymatch "~3.1.1"
1221+
braces "~3.0.2"
1222+
glob-parent "~5.1.0"
1223+
is-binary-path "~2.1.0"
1224+
is-glob "~4.0.1"
1225+
normalize-path "~3.0.0"
1226+
readdirp "~3.5.0"
1227+
optionalDependencies:
1228+
fsevents "~2.1.2"
1229+
12151230
ci-info@^2.0.0:
12161231
version "2.0.0"
12171232
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
@@ -1789,13 +1804,6 @@ fsevents@~2.1.2:
17891804
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
17901805
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
17911806

1792-
gaze@^1.1.3:
1793-
version "1.1.3"
1794-
resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a"
1795-
integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==
1796-
dependencies:
1797-
globule "^1.0.0"
1798-
17991807
gensync@^1.0.0-beta.1:
18001808
version "1.0.0-beta.1"
18011809
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
@@ -1845,7 +1853,7 @@ glob-parent@^5.1.0, glob-parent@~5.1.0:
18451853
dependencies:
18461854
is-glob "^4.0.1"
18471855

1848-
glob@^7.1.3, glob@^7.1.6, glob@~7.1.1:
1856+
glob@^7.1.3, glob@^7.1.6:
18491857
version "7.1.6"
18501858
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
18511859
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
@@ -1881,15 +1889,6 @@ globby@^11.0.0:
18811889
merge2 "^1.3.0"
18821890
slash "^3.0.0"
18831891

1884-
globule@^1.0.0:
1885-
version "1.3.2"
1886-
resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.2.tgz#d8bdd9e9e4eef8f96e245999a5dee7eb5d8529c4"
1887-
integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==
1888-
dependencies:
1889-
glob "~7.1.1"
1890-
lodash "~4.17.10"
1891-
minimatch "~3.0.2"
1892-
18931892
got@^9.6.0:
18941893
version "9.6.0"
18951894
resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
@@ -2559,11 +2558,6 @@ lodash@^4.17.19:
25592558
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
25602559
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
25612560

2562-
lodash@~4.17.10:
2563-
version "4.17.19"
2564-
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
2565-
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
2566-
25672561
log-ok@^0.1.1:
25682562
version "0.1.1"
25692563
resolved "https://registry.yarnpkg.com/log-ok/-/log-ok-0.1.1.tgz#bea3dd36acd0b8a7240d78736b5b97c65444a334"
@@ -2705,7 +2699,7 @@ mimic-response@^1.0.0, mimic-response@^1.0.1:
27052699
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
27062700
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
27072701

2708-
minimatch@^3.0.4, minimatch@~3.0.2:
2702+
minimatch@^3.0.4:
27092703
version "3.0.4"
27102704
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
27112705
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -3150,6 +3144,13 @@ readdirp@~3.4.0:
31503144
dependencies:
31513145
picomatch "^2.2.1"
31523146

3147+
readdirp@~3.5.0:
3148+
version "3.5.0"
3149+
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
3150+
integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==
3151+
dependencies:
3152+
picomatch "^2.2.1"
3153+
31533154
redent@^2.0.0:
31543155
version "2.0.0"
31553156
resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa"

0 commit comments

Comments
 (0)