Skip to content

Commit

Permalink
fix(watch): fix the watch server for esm
Browse files Browse the repository at this point in the history
  • Loading branch information
nfroidure committed Feb 29, 2024
1 parent 8ab2b10 commit 51022fd
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 43 deletions.
8 changes: 7 additions & 1 deletion packages/whook-example/src/openAPISchema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ declare namespace API {
}
export namespace GetDiagnostic {
export type Output = Responses.$200;
export type Input = {};
export type Input = {
readonly test?: Parameters.Test;
};
export namespace Responses {
export type $200 = Components.Responses.Diagnostic<200>;
}
export namespace Parameters {
export type Test = Components.Parameters.GetDiagnostic0;
}
}
export namespace GetOpenAPI {
export type Output = Responses.$200;
Expand Down Expand Up @@ -78,6 +83,7 @@ declare namespace Components {
export type Duration = NonNullable<number>;
export type PathParam1 = NonNullable<number>;
export type PathParam2 = NonNullable<string>;
export type GetDiagnostic0 = NonNullable<string>;
export type GetParameters3 = NonNullable<boolean>;
export type QueryParam = NonNullable<NonNullable<string>[]>;
export type GetParameters4 = NonNullable<NonNullable<number>[]>;
Expand Down
30 changes: 30 additions & 0 deletions packages/whook/src/services/watchResolve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
initResolve,
type LogService,
type ResolveService,
} from 'common-services';
import { name, autoService, singleton } from 'knifecycle';
import { WhookURL } from './WHOOK_RESOLVED_PLUGINS.js';

export default singleton(name('resolve', autoService(initWatchResolve)));

export type WatchResolveDependencies = {
MAIN_FILE_URL: WhookURL;
RESTARTS_COUNTER: number;
log: LogService;
};

async function initWatchResolve({
MAIN_FILE_URL,
RESTARTS_COUNTER,
log,
}: WatchResolveDependencies): Promise<ResolveService> {
const baseResolve = await initResolve({ MAIN_FILE_URL, log });

return function resolve(...args: Parameters<typeof baseResolve>): string {
return (
baseResolve(...args) +
(RESTARTS_COUNTER ? '?restartsCounter=' + RESTARTS_COUNTER : '')
);
};
}
81 changes: 39 additions & 42 deletions packages/whook/src/watch.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import chokidar from 'chokidar';
import { dirname, join } from 'node:path';
import crypto from 'crypto';
import { PassThrough } from 'stream';
import crypto from 'node:crypto';
import { PassThrough } from 'node:stream';
import { createWriteStream } from 'node:fs';
import initGenerateOpenAPITypes from './commands/generateOpenAPITypes.js';
import initGetOpenAPI from './handlers/getOpenAPI.js';
import { readFile } from 'fs';
import { promisify } from 'util';
import initWatchResolve from './services/watchResolve.js';
import { readFile } from 'node:fs';
import { promisify } from 'node:util';
import ignore from 'ignore';
import { createRequire } from 'module';
import { AppEnvVars } from 'application-services';
import { fileURLToPath } from 'url';
import type { Dependencies, Knifecycle } from 'knifecycle';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { type Dependencies, Knifecycle, constant } from 'knifecycle';
import type { DelayService, LogService } from 'common-services';
import type { OpenAPITypesConfig } from './commands/generateOpenAPITypes.js';

const require = createRequire(import.meta.url);
let $instance: Knifecycle;
let log: LogService;
let delay: DelayService;
Expand Down Expand Up @@ -44,6 +43,7 @@ export async function watchDevServer<T extends Dependencies>(
injectedNames: [],
},
): Promise<void> {
let restartsCounter = 0;
let ignoreFilter;

try {
Expand All @@ -61,7 +61,7 @@ export async function watchDevServer<T extends Dependencies>(
// log('debug-stack', printStackTrace(err as Error));
}

await restartDevServer({ injectedNames, afterRestartEnd });
await restartDevServer({ injectedNames, afterRestartEnd, restartsCounter });

await new Promise<void>((resolve, reject) => {
chokidar
Expand All @@ -76,23 +76,22 @@ export async function watchDevServer<T extends Dependencies>(
reject(err);
})
.on('all', (_event, filePath) => {
const absolutePath = join(process.cwd(), filePath).replace(
/.ts$/,
'.js',
);

// TODO: determine all the files needing a complete restart
if (filePath.match(/package.*\.json/)) {
for (const key in require.cache) {
uncache(key);
}
} else {
uncache(absolutePath, true);
log(
'warning',
`☢️ - A file changed that may need a full restart (${filePath}).`,
);
}

if (delay) {
if (!delayPromise) {
delayPromise = delay.create(2000);
restartDevServer({ injectedNames, afterRestartEnd });
restartDevServer({
injectedNames,
afterRestartEnd,
restartsCounter: restartsCounter++,
});
}
}
});
Expand All @@ -102,17 +101,33 @@ export async function watchDevServer<T extends Dependencies>(
export async function restartDevServer<T extends Dependencies>({
injectedNames = [],
afterRestartEnd,
}: WatchServerArgs<T>): Promise<void> {
restartsCounter,
}: WatchServerArgs<T> & {
restartsCounter: number;
}): Promise<void> {
if ($instance) {
log('warning', '➡️ - Changes detected : Will restart the server soon...');
log(
'warning',
`➡️ - Changes detected : Will restart the server soon (${restartsCounter})...`,
);
await delayPromise;
await $instance.destroy();
}

const { runServer, prepareEnvironment, prepareServer } = await import(
join(process.cwd(), 'src', 'index.ts')
pathToFileURL(join(process.cwd(), 'src', 'index.ts')).toString() +
(restartsCounter ? '?restartsCounter=' + restartsCounter : '')
);

async function prepareWatchEnvironment<T extends Knifecycle>(
$: T = new Knifecycle() as T,
): Promise<T> {
$ = await prepareEnvironment($);
$.register(initWatchResolve);
$.register(constant('RESTARTS_COUNTER', restartsCounter));
return $;
}

const {
ENV,
OPEN_API_TYPES_CONFIG,
Expand All @@ -123,7 +138,7 @@ export async function restartDevServer<T extends Dependencies>({
log: _log,
...additionalServices
} = (await runServer(
prepareEnvironment,
prepareWatchEnvironment,
prepareServer,

[
Expand Down Expand Up @@ -206,21 +221,3 @@ export async function restartDevServer<T extends Dependencies>({
);
}
}

function uncache(key: string, recursively = false) {
const module = require.cache[key];

if (!module) {
return;
}

if (!key.endsWith('.node')) {
delete require.cache[key];
}

if (!recursively) {
return;
}

uncache((module.parent as typeof module).id);
}

0 comments on commit 51022fd

Please sign in to comment.