Skip to content

Commit b760704

Browse files
authored
refactor: move type generation responsabilit to individual plugins (#45)
1 parent 67dba90 commit b760704

File tree

6 files changed

+224
-156
lines changed

6 files changed

+224
-156
lines changed

packages/app-kit/src/analytics/analytics.ts

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1-
import { SQLWarehouseConnector } from "../connectors";
2-
import { Plugin, toPlugin } from "../plugin";
1+
import { existsSync, type FSWatcher, watch } from "node:fs";
2+
import path from "node:path";
3+
import type { WorkspaceClient } from "@databricks/sdk-experimental";
34
import type {
45
IAppRouter,
56
PluginExecuteConfig,
7+
QuerySchemas,
68
StreamExecutionSettings,
79
} from "shared";
10+
import { generateQueryRegistryTypes } from "@/utils/type-generator";
11+
import { SQLWarehouseConnector } from "../connectors";
12+
import { Plugin, toPlugin } from "../plugin";
13+
import type { Request, Response } from "../utils";
14+
import { getRequestContext } from "../utils";
815
import { queryDefaults } from "./defaults";
916
import { QueryProcessor } from "./query";
1017
import {
1118
analyticsQueryResponseSchema,
1219
type IAnalyticsConfig,
1320
type IAnalyticsQueryRequest,
1421
} from "./types";
15-
import type { Request, Response } from "../utils";
16-
import { getRequestContext } from "../utils";
17-
import type { WorkspaceClient } from "@databricks/sdk-experimental";
1822

1923
export class AnalyticsPlugin extends Plugin {
2024
name = "analytics";
@@ -27,6 +31,8 @@ export class AnalyticsPlugin extends Plugin {
2731
private SQLClient: SQLWarehouseConnector;
2832
private queryProcessor: QueryProcessor;
2933

34+
private schemaWatcher: FSWatcher | null = null;
35+
3036
constructor(config: IAnalyticsConfig) {
3137
super(config);
3238
this.config = config;
@@ -36,6 +42,10 @@ export class AnalyticsPlugin extends Plugin {
3642
timeout: config.timeout,
3743
telemetry: this.telemetry,
3844
});
45+
46+
if (process.env.NODE_ENV === "development") {
47+
this._generateQueryTypes();
48+
}
3949
}
4050

4151
injectRoutes(router: IAppRouter) {
@@ -162,6 +172,51 @@ export class AnalyticsPlugin extends Plugin {
162172

163173
async shutdown(): Promise<void> {
164174
this.streamManager.abortAll();
175+
176+
if (this.schemaWatcher) {
177+
this.schemaWatcher.close();
178+
this.schemaWatcher = null;
179+
}
180+
}
181+
182+
// generate query types for development
183+
private _generateQueryTypes() {
184+
const schemaDir = path.join(process.cwd(), "config/queries");
185+
const schemaPath = path.join(schemaDir, "schema.ts");
186+
187+
const typePath =
188+
this.config.typePath || path.join(process.cwd(), "client", "src");
189+
190+
const generate = () => {
191+
let querySchemas: QuerySchemas = {};
192+
try {
193+
delete require.cache[require.resolve(schemaPath)];
194+
querySchemas = require(schemaPath).querySchemas;
195+
} catch (error) {
196+
if (existsSync(schemaPath)) {
197+
console.warn(
198+
`[AppKit] Failed to load query schemas from ${schemaPath}:`,
199+
error instanceof Error ? error.message : error,
200+
);
201+
}
202+
}
203+
generateQueryRegistryTypes(querySchemas, typePath);
204+
};
205+
206+
generate();
207+
208+
if (existsSync(schemaPath)) {
209+
this.schemaWatcher = watch(
210+
schemaDir,
211+
{ recursive: true },
212+
(_event, filename) => {
213+
if (filename === "schema.ts") {
214+
console.log(`[AppKit] Query schema changed, regenerating types...`);
215+
generate();
216+
}
217+
},
218+
);
219+
}
165220
}
166221
}
167222

packages/app-kit/src/analytics/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { z } from "zod";
33

44
export interface IAnalyticsConfig extends BasePluginConfig {
55
timeout?: number;
6+
typePath?: string;
67
}
78

89
export interface IAnalyticsQueryRequest {

packages/app-kit/src/core/app-kit.ts

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1-
import { existsSync, type FSWatcher, watch } from "node:fs";
2-
import path from "node:path";
31
import type {
42
BasePlugin,
53
InputPluginMap,
64
OptionalConfigPluginDef,
75
PluginConstructor,
86
PluginData,
97
PluginMap,
10-
QuerySchemas,
118
} from "shared";
129
import type { TelemetryConfig } from "../telemetry";
1310
import { TelemetryManager } from "../telemetry";
14-
import { generatePluginTypes } from "./type-generator";
1511

1612
export class AppKit<TPlugins extends InputPluginMap> {
1713
private static _instance: AppKit<InputPluginMap> | null = null;
1814
private pluginInstances: Record<string, BasePlugin> = {};
1915
private setupPromises: Promise<void>[] = [];
20-
private schemaWatcher: FSWatcher | null = null;
2116

2217
private constructor(config: { plugins: TPlugins }) {
2318
const { plugins, ...globalConfig } = config;
@@ -102,20 +97,9 @@ export class AppKit<TPlugins extends InputPluginMap> {
10297

10398
await Promise.all(AppKit._instance.setupPromises);
10499

105-
if (process.env.NODE_ENV === "development") {
106-
AppKit._instance._generatePluginTypes(rawPlugins);
107-
}
108-
109100
return AppKit._instance as unknown as PluginMap<T>;
110101
}
111102

112-
cleanup() {
113-
if (this.schemaWatcher) {
114-
this.schemaWatcher.close();
115-
this.schemaWatcher = null;
116-
}
117-
}
118-
119103
private static preparePlugins(
120104
plugins: PluginData<PluginConstructor, unknown, string>[],
121105
) {
@@ -128,60 +112,6 @@ export class AppKit<TPlugins extends InputPluginMap> {
128112
}
129113
return result;
130114
}
131-
132-
private _generatePluginTypes(
133-
rawPlugins: PluginData<PluginConstructor, unknown, string>[],
134-
) {
135-
const serverPlugin = rawPlugins.find((p) => p.name === "server");
136-
const staticPath = (serverPlugin?.config as { staticPath?: string })
137-
?.staticPath;
138-
139-
const schemaDir = path.join(process.cwd(), "config/queries");
140-
const querySchemaPath = path.join(schemaDir, "schema.ts");
141-
142-
const generate = () => {
143-
let querySchemas: QuerySchemas = {};
144-
145-
try {
146-
delete require.cache[require.resolve(querySchemaPath)];
147-
querySchemas = require(querySchemaPath).querySchemas;
148-
} catch (error) {
149-
if (existsSync(querySchemaPath)) {
150-
console.warn(
151-
`[AppKit] Failed to load query schemas from ${querySchemaPath}:`,
152-
error instanceof Error ? error.message : error,
153-
);
154-
}
155-
}
156-
157-
generatePluginTypes(
158-
rawPlugins.map((p) => ({ name: p.name })),
159-
querySchemas,
160-
staticPath,
161-
);
162-
};
163-
generate();
164-
165-
if (this.schemaWatcher) {
166-
this.schemaWatcher.close();
167-
this.schemaWatcher = null;
168-
}
169-
170-
if (existsSync(querySchemaPath)) {
171-
this.schemaWatcher = watch(
172-
schemaDir,
173-
{ recursive: true },
174-
(_event, filename) => {
175-
if (filename?.endsWith(".ts")) {
176-
console.log(
177-
`[AppKit] Query schema changed, regenerating types for ${filename}`,
178-
);
179-
generate();
180-
}
181-
},
182-
);
183-
}
184-
}
185115
}
186116

187117
export async function createApp<

packages/app-kit/src/core/type-generator.ts

Lines changed: 0 additions & 81 deletions
This file was deleted.

packages/app-kit/src/server/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import path from "node:path";
44
import dotenv from "dotenv";
55
import express from "express";
66
import type { PluginPhase } from "shared";
7+
import { generatePluginRegistryTypes } from "@/utils/type-generator";
78
import { Plugin, toPlugin } from "../plugin";
89
import { instrumentations } from "../telemetry";
910
import { databricksClientMiddleware, isRemoteServerEnabled } from "../utils";
@@ -68,6 +69,11 @@ export class ServerPlugin extends Plugin {
6869
this.serverApplication.use(await databricksClientMiddleware());
6970

7071
this.extendRoutes();
72+
73+
if (process.env.NODE_ENV === "development") {
74+
generatePluginRegistryTypes(this.config.plugins, this.config.staticPath);
75+
}
76+
7177
for (const extension of this.serverExtensions) {
7278
extension(this.serverApplication);
7379
}

0 commit comments

Comments
 (0)