Skip to content

Commit b5532cc

Browse files
committed
feat(cli): implement start --watch feature
1 parent 390df54 commit b5532cc

File tree

7 files changed

+73
-19
lines changed

7 files changed

+73
-19
lines changed

labs/playground1/sqls/artist/artist.sql

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ select
22
*
33
from "artists"
44
where
5-
ConstituentID = {{ context.params.id }}
5+
ConstituentID = {{ context.params.id }};

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"private": true,
99
"dependencies": {
1010
"@koa/cors": "^3.3.0",
11+
"chokidar": "^3.5.3",
1112
"class-validator": "^0.13.2",
1213
"commander": "^9.4.0",
1314
"dayjs": "^1.11.2",

packages/cli/src/commands/build.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ const defaultOptions: BuildCommandOptions = {
1212
config: './vulcan.yaml',
1313
};
1414

15+
export const mergeBuildDefaultOption = (
16+
options: Partial<BuildCommandOptions>
17+
) => {
18+
return {
19+
...defaultOptions,
20+
...options,
21+
} as BuildCommandOptions;
22+
};
23+
1524
export const buildVulcan = async (options: BuildCommandOptions) => {
1625
const configPath = path.resolve(process.cwd(), options.config);
1726
const config: any = jsYAML.load(await fs.readFile(configPath, 'utf-8'));
@@ -36,9 +45,5 @@ export const buildVulcan = async (options: BuildCommandOptions) => {
3645
export const handleBuild = async (
3746
options: Partial<BuildCommandOptions>
3847
): Promise<void> => {
39-
options = {
40-
...defaultOptions,
41-
...options,
42-
};
43-
await buildVulcan(options as BuildCommandOptions);
48+
await buildVulcan(mergeBuildDefaultOption(options));
4449
};

packages/cli/src/commands/serve.ts

+27-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import * as jsYAML from 'js-yaml';
22
import { promises as fs } from 'fs';
33
import * as path from 'path';
4-
import { addShutdownJob, localModulePath, logger } from '../utils';
4+
import {
5+
addShutdownJob,
6+
localModulePath,
7+
logger,
8+
removeShutdownJob,
9+
} from '../utils';
510

611
export interface ServeCommandOptions {
712
config: string;
@@ -13,6 +18,15 @@ const defaultOptions: ServeCommandOptions = {
1318
port: 3000,
1419
};
1520

21+
export const mergeServeDefaultOption = (
22+
options: Partial<ServeCommandOptions>
23+
) => {
24+
return {
25+
...defaultOptions,
26+
...options,
27+
} as ServeCommandOptions;
28+
};
29+
1630
export const serveVulcan = async (options: ServeCommandOptions) => {
1731
const configPath = path.resolve(process.cwd(), options.config);
1832
const config: any = jsYAML.load(await fs.readFile(configPath, 'utf-8'));
@@ -25,19 +39,24 @@ export const serveVulcan = async (options: ServeCommandOptions) => {
2539
const server = new VulcanServer(config);
2640
await server.start(options.port);
2741
logger.info(`Server is listening at port ${options.port}.`);
28-
addShutdownJob(async () => {
42+
43+
const closeServerJob = async () => {
2944
logger.info(`Stopping server...`);
3045
await server.close();
3146
logger.info(`Server stopped`);
32-
});
47+
};
48+
addShutdownJob(closeServerJob);
49+
50+
return {
51+
stopServer: async () => {
52+
removeShutdownJob(closeServerJob);
53+
await closeServerJob();
54+
},
55+
};
3356
};
3457

3558
export const handleServe = async (
3659
options: Partial<ServeCommandOptions>
3760
): Promise<void> => {
38-
options = {
39-
...defaultOptions,
40-
...options,
41-
};
42-
await serveVulcan(options as ServeCommandOptions);
61+
await serveVulcan(mergeServeDefaultOption(options));
4362
};

packages/cli/src/commands/start.ts

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1-
import { BuildCommandOptions, handleBuild } from './build';
2-
import { handleServe, ServeCommandOptions } from './serve';
1+
import {
2+
BuildCommandOptions,
3+
buildVulcan,
4+
mergeBuildDefaultOption,
5+
} from './build';
6+
import {
7+
mergeServeDefaultOption,
8+
ServeCommandOptions,
9+
serveVulcan,
10+
} from './serve';
11+
import * as chokidar from 'chokidar';
12+
import { debounce } from 'lodash';
313

414
export const handleStart = async (
515
options: Partial<BuildCommandOptions & ServeCommandOptions>
616
): Promise<void> => {
7-
await handleBuild(options);
8-
await handleServe(options);
17+
const buildOptions = mergeBuildDefaultOption(options);
18+
const serveOptions = mergeServeDefaultOption(options);
19+
20+
let stopServer: (() => Promise<any>) | undefined;
21+
22+
const restartServer = async () => {
23+
if (stopServer) await stopServer();
24+
await buildVulcan(buildOptions);
25+
stopServer = (await serveVulcan(serveOptions)).stopServer;
26+
};
27+
28+
await restartServer();
29+
30+
chokidar
31+
.watch(['./sqls/**/*.sql'], { ignoreInitial: true })
32+
.on('all', debounce(restartServer, 1000));
933
};

packages/cli/src/utils/shutdown.ts

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ export const addShutdownJob = (job: JobBeforeShutdown) => {
88
shutdownJobs.push(job);
99
};
1010

11+
export const removeShutdownJob = (job: JobBeforeShutdown) => {
12+
const index = shutdownJobs.indexOf(job);
13+
if (index >= 0) shutdownJobs.splice(index, 1);
14+
};
15+
1116
export const runShutdownJobs = async () => {
1217
logger.info('Ctrl-C signal caught, stopping services...');
1318
await Promise.all(shutdownJobs.map((job) => job()));

yarn.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -2028,7 +2028,7 @@ chardet@^0.7.0:
20282028
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
20292029
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
20302030

2031-
chokidar@^3.5.1:
2031+
chokidar@^3.5.1, chokidar@^3.5.3:
20322032
version "3.5.3"
20332033
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
20342034
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==

0 commit comments

Comments
 (0)