Skip to content

Commit cb64d25

Browse files
committed
fix: handle hmr properly
1 parent b01fc76 commit cb64d25

File tree

9 files changed

+4186
-18227
lines changed

9 files changed

+4186
-18227
lines changed

apps/test-bot/src/app/commands/(general)/dog.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const command: CommandData = {
66
};
77

88
export const chatInput: SlashCommand = async (ctx) => {
9-
await ctx.interaction.reply('Hello from dog!');
9+
await ctx.interaction.reply('Hello from dog command!');
1010
};
1111

1212
export const message: MessageCommand = async (ctx) => {

bun.lock

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

package.json

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,39 @@
33
"version": "0.0.0",
44
"private": true,
55
"license": "MIT",
6+
"workspaces": [
7+
"packages/*",
8+
"apps/*"
9+
],
610
"scripts": {
7-
"dev": "turbo dev",
8-
"lint": "turbo lint && prettier --check ./ --ignore-path=.prettierignore",
9-
"build": "turbo lint && turbo build",
10-
"publish-package": "turbo publish-package",
11-
"docgen": "tsx ./scripts/docgen.ts && pnpm format",
11+
"lint": "bun lint --filter=\"./packages/*\" && prettier --check ./ --ignore-path=.prettierignore",
12+
"build": "bun run --filter=\"./packages/*\" build",
13+
"publish-package": "bun publish-package",
14+
"build-docs": "bun run --filter=\"./apps/website\" build",
15+
"docgen": "tsx ./scripts/docgen.ts && bun format",
1216
"format": "prettier --write ./ --ignore-path=.prettierignore"
1317
},
1418
"devDependencies": {
1519
"@types/node": "^22.10.2",
1620
"micro-docgen": "^0.3.5",
1721
"prettier": "^3.0.3",
18-
"tsx": "^4.7.0",
19-
"turbo": "^2.3.3"
22+
"tsx": "^4.7.0"
2023
},
21-
"packageManager": "pnpm@9.15.0",
22-
"pnpm": {
23-
"overrides": {
24-
"katex@>=0.11.0 <0.16.10": ">=0.16.10",
25-
"katex@>=0.15.4 <0.16.10": ">=0.16.10",
26-
"katex@>=0.10.0-beta <0.16.10": ">=0.16.10",
27-
"vite@>=5.0.0 <=5.0.12": ">=5.0.13",
28-
"braces@<3.0.3": ">=3.0.3",
29-
"micromatch@<4.0.8": ">=4.0.8",
30-
"vite@>=5.0.0 <=5.1.7": ">=5.1.8",
31-
"vite@>=5.0.0 <5.1.8": ">=5.1.8",
32-
"rollup@>=4.0.0 <4.22.4": ">=4.22.4",
33-
"cross-spawn@>=7.0.0 <7.0.5": ">=7.0.5",
34-
"nanoid@<3.3.8": "3.3.8",
35-
"next@>=15.0.0 <15.1.2": ">=15.1.2",
36-
"undici@>=6.0.0 <6.21.1": ">=6.21.1",
37-
"vite@>=6.0.0 <=6.0.8": ">=6.0.9",
38-
"katex@>=0.12.0 <=0.16.20": ">=0.16.21"
39-
}
24+
"overrides": {
25+
"katex@>=0.11.0 <0.16.10": ">=0.16.10",
26+
"katex@>=0.15.4 <0.16.10": ">=0.16.10",
27+
"katex@>=0.10.0-beta <0.16.10": ">=0.16.10",
28+
"vite@>=5.0.0 <=5.0.12": ">=5.0.13",
29+
"braces@<3.0.3": ">=3.0.3",
30+
"micromatch@<4.0.8": ">=4.0.8",
31+
"vite@>=5.0.0 <=5.1.7": ">=5.1.8",
32+
"vite@>=5.0.0 <5.1.8": ">=5.1.8",
33+
"rollup@>=4.0.0 <4.22.4": ">=4.22.4",
34+
"cross-spawn@>=7.0.0 <7.0.5": ">=7.0.5",
35+
"nanoid@<3.3.8": "3.3.8",
36+
"next@>=15.0.0 <15.1.2": ">=15.1.2",
37+
"undici@>=6.0.0 <6.21.1": ">=6.21.1",
38+
"vite@>=6.0.0 <=6.0.8": ">=6.0.9",
39+
"katex@>=0.12.0 <=0.16.20": ">=0.16.21"
4040
}
4141
}

packages/commandkit/src/cli/app-process.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1-
import { spawn } from 'node:child_process';
2-
import { DevEnv, devEnvFileArgs, prodEnvFileArgs } from './env';
1+
import { IOType, spawn } from 'node:child_process';
2+
import { DevEnv } from './env';
33
import { join } from 'node:path';
44
import { existsSync } from 'node:fs';
55
import { panic } from './common';
66

7+
function getStdio(supportsCommands: boolean) {
8+
if (supportsCommands) {
9+
return ['pipe', 'pipe', 'pipe', 'ipc'];
10+
}
11+
12+
return ['pipe', 'pipe', 'pipe'];
13+
}
14+
715
export function createAppProcess(
816
fileName: string,
917
cwd: string,
@@ -13,6 +21,8 @@ export function createAppProcess(
1321
panic(`Could not locate the entrypoint file: ${fileName}`);
1422
}
1523

24+
const stdio = getStdio(isDev) as IOType[];
25+
1626
const ps = spawn(
1727
'node',
1828
[
@@ -21,10 +31,10 @@ export function createAppProcess(
2131
fileName,
2232
],
2333
{
24-
cwd: cwd,
34+
cwd,
2535
windowsHide: true,
2636
env: DevEnv(),
27-
stdio: ['pipe', 'pipe', 'pipe'],
37+
stdio,
2838
},
2939
);
3040

packages/commandkit/src/cli/development.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { isCompilerPlugin } from '../plugins';
44
import { createAppProcess } from './app-process';
55
import { buildApplication } from './build';
66
import { watch } from 'chokidar';
7-
import { ChildProcessWithoutNullStreams } from 'child_process';
87
import { readdirSync } from 'node:fs';
98
import { debounce } from '../utils/utilities';
109
import colors from '../utils/colors';
10+
import { ChildProcess } from 'node:child_process';
1111

1212
async function buildAndStart(configPath: string, skipStart = false) {
1313
const config = await loadConfigFile(configPath);
@@ -22,7 +22,13 @@ async function buildAndStart(configPath: string, skipStart = false) {
2222

2323
if (skipStart) return null as never;
2424

25-
return createAppProcess(mainFile, configPath, true);
25+
const ps = createAppProcess(mainFile, configPath, true);
26+
27+
ps.on('message', (message) => {
28+
console.log(`Received message from child process: ${message}`);
29+
});
30+
31+
return ps;
2632
}
2733

2834
const isCommandSource = (p: string) =>
@@ -42,17 +48,18 @@ export async function bootstrapDevelopmentServer(configPath?: string) {
4248
ignoreInitial: true,
4349
});
4450

45-
let ps: ChildProcessWithoutNullStreams | null = null;
51+
let ps: ChildProcess | null = null;
4652

4753
const performHMR = debounce(async (path?: string): Promise<boolean> => {
4854
if (!path || !ps) return false;
55+
if (!ps.send) return false;
4956

5057
if (isCommandSource(path)) {
5158
console.log(
5259
`${colors.cyanBright('Reloading command(s) at ')} ${colors.yellowBright(path)}`,
5360
);
5461
await buildAndStart(cwd, true);
55-
ps.stdin.write(`COMMANDKIT_EVENT=reload-commands|${path}\n`);
62+
ps.send({ event: 'reload-commands', path });
5663
return true;
5764
}
5865

@@ -61,7 +68,7 @@ export async function bootstrapDevelopmentServer(configPath?: string) {
6168
`${colors.cyanBright('Reloading event(s) at ')} ${colors.yellowBright(path)}`,
6269
);
6370
await buildAndStart(cwd, true);
64-
ps.stdin.write(`COMMANDKIT_EVENT=reload-events|${path}\n`);
71+
ps.send({ event: 'reload-events', path });
6572
return true;
6673
}
6774

@@ -70,15 +77,20 @@ export async function bootstrapDevelopmentServer(configPath?: string) {
7077
`${colors.cyanBright('Reloading locale(s) at ')} ${colors.yellowBright(path)}`,
7178
);
7279
await buildAndStart(cwd, true);
73-
ps.stdin.write(`COMMANDKIT_EVENT=reload-locales|${path}\n`);
80+
ps.send({ event: 'reload-locales', path });
7481
return true;
7582
}
7683

7784
return false;
7885
}, 300);
7986

8087
const hmrHandler = async (path: string) => {
81-
if (await performHMR(path)) return;
88+
const hmr = await performHMR(path);
89+
if (hmr) return;
90+
91+
console.log(
92+
`${colors.yellowBright('⚡️ Performing full restart due to the changes in')} ${colors.cyanBright(path)}`,
93+
);
8294

8395
ps?.kill();
8496

@@ -97,15 +109,15 @@ export async function bootstrapDevelopmentServer(configPath?: string) {
97109
break;
98110
case 'rc':
99111
console.log(`Received reload commands command, reloading...`);
100-
ps?.stdin.write(`COMMANDKIT_EVENT=reload-commands\n`);
112+
ps?.send({ event: 'reload-commands' });
101113
break;
102114
case 're':
103115
console.log(`Received reload events command, reloading...`);
104-
ps?.stdin.write(`COMMANDKIT_EVENT=reload-events\n`);
116+
ps?.send({ event: 'reload-events' });
105117
break;
106118
case 'rl':
107119
console.log(`Received reload locales command, reloading...`);
108-
ps?.stdin.write(`COMMANDKIT_EVENT=reload-locales\n`);
120+
ps?.send({ event: 'reload-locales' });
109121
break;
110122
}
111123
});

packages/commandkit/src/utils/dev-hooks.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,23 @@ import type { CommandKit } from '../CommandKit';
22
import { Logger } from '../logger/Logger';
33
import { COMMANDKIT_IS_DEV } from './constants';
44

5-
const EVENT_PATTERN = /^COMMANDKIT_EVENT=(\w+)(\|(.+))?$/;
5+
interface IpcMessageCommand {
6+
event: string;
7+
path?: string;
8+
}
69

710
export function registerDevHooks(commandkit: CommandKit) {
811
if (!COMMANDKIT_IS_DEV) return;
912

10-
process.stdin.on('data', (chunk) => {
11-
const input = chunk.toString().trim();
13+
process.on('message', (message) => {
14+
if (typeof message !== 'object' || message === null) return;
1215

13-
const match = input.match(EVENT_PATTERN);
14-
if (!match) return;
16+
const { event, path } = message as IpcMessageCommand;
17+
if (!event) return;
1518

16-
const [, event, , path] = match;
17-
Logger.info(`Received HMR event: ${event}${path ? ` for ${path}` : ''}`);
19+
if (process.env.COMMANDKIT_DEBUG_HMR === 'true') {
20+
Logger.info(`Received HMR event: ${event}${path ? ` for ${path}` : ''}`);
21+
}
1822

1923
switch (event) {
2024
case 'reload-commands':

packages/commandkit/src/utils/utilities.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,24 @@ export function debounce<R, F extends (...args: any[]) => R>(
4242
ms: number,
4343
): F {
4444
let timer: NodeJS.Timeout | null = null;
45+
let resolve: ((value: R | PromiseLike<R>) => void) | null = null;
4546

4647
return ((...args: any[]) => {
4748
if (timer) {
4849
clearTimeout(timer);
50+
if (resolve) {
51+
resolve(null as unknown as R); // Resolve with null if debounced
52+
}
4953
}
5054

51-
timer = setTimeout(() => {
52-
fn(...args);
53-
timer = null;
54-
}, ms);
55+
return new Promise<R>((res) => {
56+
resolve = res;
57+
timer = setTimeout(() => {
58+
const result = fn(...args);
59+
res(result);
60+
timer = null;
61+
resolve = null;
62+
}, ms);
63+
});
5564
}) as F;
5665
}

0 commit comments

Comments
 (0)