Skip to content

Commit 050d99a

Browse files
Fix watch mode not reloading after files with compiler errors are fixed (#27)
1 parent dca9685 commit 050d99a

File tree

3 files changed

+45
-19
lines changed

3 files changed

+45
-19
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ This changelog documents the changes between release versions.
77
## [Unreleased]
88
Changes to be included in the next upcoming release
99

10+
- Fixed watch mode not reloading after files with compiler errors are changed [#27](https://github.com/hasura/ndc-nodejs-lambda/pull/27)
11+
1012
## [1.2.0] - 2024-03-18
1113
- Improved error messages when unsupported enum types or unions of literal types are found, and allow these types to be used in relaxed types mode ([#17](https://github.com/hasura/ndc-nodejs-lambda/pull/17))
1214
- Improved naming of types that reside outside of the main `functions.ts` file. Type names will now only be prefixed with a disambiguator if there is a naming conflict detected (ie. where two different types use the same name). Anonymous types are now also named in a shorter way. ([#21](https://github.com/hasura/ndc-nodejs-lambda/pull/21))

ndc-lambda-sdk/bin/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const watchMode = hostOpts?.watch ?? false;
2727

2828
const hostScriptPath = path.resolve(__dirname, "../dist/src/host.js")
2929
const projectArgs = tsConfigFileLocation ? ["--project", tsConfigFileLocation] : []
30-
const tsNodeArgs = [...projectArgs, "--transpile-only", hostScriptPath, ...process.argv.slice(2)];
30+
const tsNodeArgs = [...projectArgs, "--pretty", hostScriptPath, ...process.argv.slice(2)];
3131

3232
const [command, args] =
3333
watchMode

ndc-lambda-sdk/src/connector.ts

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import { RuntimeFunctions, executeMutation, executeQuery } from "./execution";
66

77
export type Configuration = {
88
functionsSchema: FunctionsSchema
9+
runtimeFunctions: RuntimeFunctions
910
};
1011

11-
export type State = {
12-
runtimeFunctions: RuntimeFunctions
13-
}
12+
export type State = {}
1413

1514
export type ConnectorOptions = {
1615
functionsFilePath: string
@@ -22,23 +21,48 @@ export function createConnector(options: ConnectorOptions): sdk.Connector<Config
2221
const connector: sdk.Connector<Configuration, State> = {
2322

2423
parseConfiguration: async function (configurationDir: string): Promise<Configuration> {
25-
const schemaResults = deriveSchema(functionsFilePath);
26-
printCompilerDiagnostics(schemaResults.compilerDiagnostics);
27-
printFunctionIssues(schemaResults.functionIssues);
28-
printRelaxedTypesWarning(schemaResults.functionsSchema);
29-
return {
30-
functionsSchema: schemaResults.functionsSchema
24+
// We need to try imporing the functions code via require before doing schema inference because
25+
// during watch mode we need it to be registered in the watching system so when the files are
26+
// changed we reload. If the files fail to compile, ts-node will print the diagnostic errors on the
27+
// terminal for us
28+
let runtimeFunctions: RuntimeFunctions | undefined = undefined;
29+
try {
30+
runtimeFunctions = require(functionsFilePath);
31+
} catch (e) {
32+
console.error(`${e}`); // Print the compiler errors produced by ts-node
33+
runtimeFunctions = undefined;
34+
}
35+
36+
// If the functions successfully loaded (ie. compiled), let's derive the schema.
37+
// Unfortunately this means we've typechecked everything twice, but that seems unavoidable without
38+
// implementing our own hot-reloading system instead of using ts-node-dev.
39+
if (runtimeFunctions !== undefined) {
40+
const schemaResults = deriveSchema(functionsFilePath);
41+
printCompilerDiagnostics(schemaResults.compilerDiagnostics); // Should never have any of these, since we've already tried compiling the code above
42+
printFunctionIssues(schemaResults.functionIssues);
43+
printRelaxedTypesWarning(schemaResults.functionsSchema);
44+
45+
return {
46+
functionsSchema: schemaResults.functionsSchema,
47+
runtimeFunctions,
48+
}
49+
}
50+
// If the functions did not compile, just have an empty schema, the user will need to correct
51+
// their code before we can derive a schema
52+
else {
53+
return {
54+
functionsSchema: {
55+
functions: {},
56+
objectTypes: {},
57+
scalarTypes: {},
58+
},
59+
runtimeFunctions: {}
60+
}
3161
}
3262
},
3363

3464
tryInitState: async function (configuration: Configuration, metrics: unknown): Promise<State> {
35-
if (Object.keys(configuration.functionsSchema.functions).length === 0) {
36-
// If there are no declared functions, don't bother trying to load the code.
37-
// There's very likely to be compiler errors during schema inference that will
38-
// block the load anyway, or the user hasn't written anything useful yet.
39-
return { runtimeFunctions: {} }
40-
}
41-
return { runtimeFunctions: require(functionsFilePath) }
65+
return {};
4266
},
4367

4468
getCapabilities: function (configuration: Configuration): sdk.CapabilitiesResponse {
@@ -58,11 +82,11 @@ export function createConnector(options: ConnectorOptions): sdk.Connector<Config
5882
},
5983

6084
query: async function (configuration: Configuration, state: State, request: sdk.QueryRequest): Promise<sdk.QueryResponse> {
61-
return await executeQuery(request, configuration.functionsSchema, state.runtimeFunctions);
85+
return await executeQuery(request, configuration.functionsSchema, configuration.runtimeFunctions);
6286
},
6387

6488
mutation: async function (configuration: Configuration, state: State, request: sdk.MutationRequest): Promise<sdk.MutationResponse> {
65-
return await executeMutation(request, configuration.functionsSchema, state.runtimeFunctions);
89+
return await executeMutation(request, configuration.functionsSchema, configuration.runtimeFunctions);
6690
},
6791

6892
queryExplain: function (configuration: Configuration, state: State, request: sdk.QueryRequest): Promise<sdk.ExplainResponse> {

0 commit comments

Comments
 (0)