From fa00b074b976ecb5ca6d5e47b65cac0c91f88353 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:49:11 +0200 Subject: [PATCH 1/2] Work on decoupling studio server constituents --- packages/toolpad-studio/src/constants.ts | 1 - .../toolpad-studio/src/server/DataManager.ts | 3 +-- .../toolpad-studio/src/server/EnvManager.ts | 2 -- .../src/server/FunctionsManager.ts | 4 --- .../src/server/appServerWorker.ts | 5 +--- packages/toolpad-studio/src/server/index.ts | 17 +++---------- .../toolpad-studio/src/server/localMode.ts | 25 ++++--------------- .../src/server/projectRpcServer.ts | 3 --- .../src/server/toolpadAppServer.ts | 19 +++----------- .../QueryEditor/QueryEditorPanel.tsx | 3 --- .../toolpadDataSources/googleSheets/server.ts | 23 +++++++++-------- .../src/toolpadDataSources/server.ts | 3 +-- packages/toolpad-studio/src/types.ts | 8 ------ 13 files changed, 26 insertions(+), 90 deletions(-) diff --git a/packages/toolpad-studio/src/constants.ts b/packages/toolpad-studio/src/constants.ts index 319baddce42..276218063e2 100644 --- a/packages/toolpad-studio/src/constants.ts +++ b/packages/toolpad-studio/src/constants.ts @@ -1,5 +1,4 @@ export const WINDOW_PROP_TOOLPAD_APP_RENDER_PARAMS = '__TOOLPAD_APP_RENDER_PARAMS__'; -export const RUNTIME_CONFIG_WINDOW_PROPERTY = '__TOOLPAD_RUNTIME_CONFIG__'; export const INITIAL_STATE_WINDOW_PROPERTY = '__initialToolpadState__'; export const TOOLPAD_TARGET_CE = 'CE'; diff --git a/packages/toolpad-studio/src/server/DataManager.ts b/packages/toolpad-studio/src/server/DataManager.ts index a45439e064a..40d15fea070 100644 --- a/packages/toolpad-studio/src/server/DataManager.ts +++ b/packages/toolpad-studio/src/server/DataManager.ts @@ -6,7 +6,7 @@ import cors from 'cors'; import invariant from 'invariant'; import { errorFrom, serializeError, SerializedError } from '@toolpad/utils/errors'; import * as appDom from '@toolpad/studio-runtime/appDom'; -import type { RuntimeConfig, Methods, ServerDataSource, ToolpadProjectOptions } from '../types'; +import type { Methods, ServerDataSource, ToolpadProjectOptions } from '../types'; import serverDataSources from '../toolpadDataSources/server'; import applyTransform from '../toolpadDataSources/applyTransform'; import { asyncHandler } from '../utils/express'; @@ -29,7 +29,6 @@ interface IToolpadProject { saveDom(dom: appDom.AppDom): Promise; functionsManager: FunctionsManager; envManager: EnvManager; - getRuntimeConfig: () => Promise; } /** diff --git a/packages/toolpad-studio/src/server/EnvManager.ts b/packages/toolpad-studio/src/server/EnvManager.ts index 752909aa5c6..5f6336504dc 100644 --- a/packages/toolpad-studio/src/server/EnvManager.ts +++ b/packages/toolpad-studio/src/server/EnvManager.ts @@ -11,7 +11,6 @@ interface IToolpadProject { options: ToolpadProjectOptions; events: Emitter; getRoot(): string; - invalidateQueries(): void; } /** @@ -88,7 +87,6 @@ export default class EnvManager { this.loadEnvFile(); this.project.events.emit('envChanged', {}); - this.project.invalidateQueries(); }; this.watcher.on('add', handleChange); diff --git a/packages/toolpad-studio/src/server/FunctionsManager.ts b/packages/toolpad-studio/src/server/FunctionsManager.ts index 2fa95cc1533..0c94d231b60 100644 --- a/packages/toolpad-studio/src/server/FunctionsManager.ts +++ b/packages/toolpad-studio/src/server/FunctionsManager.ts @@ -20,7 +20,6 @@ import * as url from 'node:url'; import type { GridRowId } from '@mui/x-data-grid'; import invariant from 'invariant'; import { Awaitable } from '@toolpad/utils/types'; -import EnvManager from './EnvManager'; import { ProjectEvents, ToolpadProjectOptions } from '../types'; import * as functionsRuntime from './functionsRuntime'; import type { ExtractTypesParams, IntrospectionResult } from './functionsTypesWorker'; @@ -104,8 +103,6 @@ interface IToolpadProject { events: Emitter; getRoot(): string; getOutputFolder(): string; - envManager: EnvManager; - invalidateQueries(): void; } export default class FunctionsManager { @@ -200,7 +197,6 @@ export default class FunctionsManager { this.buildErrors = args.errors; - this.project.invalidateQueries(); this.project.events.emit('functionsChanged', {}); }; diff --git a/packages/toolpad-studio/src/server/appServerWorker.ts b/packages/toolpad-studio/src/server/appServerWorker.ts index 9e65f9e753b..e65946f7df7 100644 --- a/packages/toolpad-studio/src/server/appServerWorker.ts +++ b/packages/toolpad-studio/src/server/appServerWorker.ts @@ -4,7 +4,6 @@ import type { Plugin } from 'vite'; import { createRpcClient } from '@toolpad/utils/workerRpc'; import type * as appDom from '@toolpad/studio-runtime/appDom'; import { createViteConfig, getEditorHtmlContent } from './toolpadAppBuilder'; -import type { RuntimeConfig } from '../types'; import type { ComponentEntry, PagesManifest } from './localMode'; import createRuntimeState from '../runtime/createRuntimeState'; import { postProcessHtml } from './toolpadAppServer'; @@ -29,13 +28,12 @@ invariant( export interface ToolpadAppDevServerParams { outDir: string; - config: RuntimeConfig; root: string; base: string; customServer: boolean; } -function devServerPlugin({ config }: ToolpadAppDevServerParams): Plugin { +function devServerPlugin({}: ToolpadAppDevServerParams): Plugin { return { name: 'toolpad-dev-server', @@ -51,7 +49,6 @@ function devServerPlugin({ config }: ToolpadAppDevServerParams): Plugin { let html = await viteServer.transformIndexHtml(req.url, template); html = postProcessHtml(html, { - config, initialState: createRuntimeState({ dom }), }); diff --git a/packages/toolpad-studio/src/server/index.ts b/packages/toolpad-studio/src/server/index.ts index c2e08b68559..0dae1d2d3c8 100644 --- a/packages/toolpad-studio/src/server/index.ts +++ b/packages/toolpad-studio/src/server/index.ts @@ -52,11 +52,7 @@ async function createDevHandler(project: ToolpadProject) { const appServerPath = path.resolve(currentDirectory, '../cli/appServerWorker.mjs'); - const [wsPort, devPort, runtimeConfig] = await Promise.all([ - getPort(), - getPort(), - project.getRuntimeConfig(), - ]); + const [wsPort, devPort] = await Promise.all([getPort(), getPort()]); const mainThreadRpcChannel = new MessageChannel(); const worker = new Worker(appServerPath, { @@ -64,7 +60,6 @@ async function createDevHandler(project: ToolpadProject) { toolpadDevMode: project.options.toolpadDevMode, outDir: project.getAppOutputFolder(), base: project.options.base, - config: runtimeConfig, root: project.getRoot(), port: devPort, mainThreadRpcPort: mainThreadRpcChannel.port1, @@ -198,7 +193,6 @@ export interface ToolpadHandlerConfig { dev: boolean; dir: string; base: string; - externalUrl: string; toolpadDevMode?: boolean; } @@ -206,9 +200,8 @@ export async function createHandler({ dev = false, dir = './toolpad', base = '/prod', - externalUrl = 'http://localhost:3000', }: ToolpadHandlerConfig): Promise { - const project = await initProject({ dev, dir, externalUrl, base, customServer: true }); + const project = await initProject({ dev, dir, base, customServer: true }); await project.start(); const appHandler = await createToolpadAppHandler(project); @@ -223,14 +216,13 @@ export async function createHandler({ async function createToolpadHandler({ dev, - externalUrl, base, dir, toolpadDevMode, }: ToolpadHandlerConfig): Promise { const editorBasename = '/_toolpad'; - const project = await initProject({ toolpadDevMode, dev, dir, externalUrl, base }); + const project = await initProject({ toolpadDevMode, dev, dir, base }); await project.checkPlan(); await project.start(); @@ -373,15 +365,12 @@ export async function runApp({ } } - const externalUrl = process.env.TOOLPAD_EXTERNAL_URL || `http://localhost:${port}`; - const server = await startToolpadServer({ dev, base, dir, port, toolpadDevMode: !!process.env.TOOLPAD_NEXT_DEV || toolpadDevMode, - externalUrl, }); const toolpadUrl = `http://localhost:${server.port}/`; diff --git a/packages/toolpad-studio/src/server/localMode.ts b/packages/toolpad-studio/src/server/localMode.ts index 56d88c31ae1..70bde0f5528 100644 --- a/packages/toolpad-studio/src/server/localMode.ts +++ b/packages/toolpad-studio/src/server/localMode.ts @@ -53,12 +53,7 @@ import { ResponseType as AppDomRestResponseType, } from '../toolpadDataSources/rest/types'; import { LocalQuery } from '../toolpadDataSources/local/types'; -import type { - RuntimeConfig, - ProjectEvents, - ToolpadProjectOptions, - CodeEditorFileType, -} from '../types'; +import type { ProjectEvents, ToolpadProjectOptions, CodeEditorFileType } from '../types'; import EnvManager from './EnvManager'; import FunctionsManager, { CreateDataProviderOptions } from './FunctionsManager'; import { VersionInfo, checkVersion } from './versionInfo'; @@ -1015,8 +1010,6 @@ class ToolpadProject { dataManager: DataManager; - invalidateQueries: () => void; - private alertedMissingVars = new Set(); private lastVersionCheck = 0; @@ -1045,7 +1038,7 @@ class ToolpadProject { this.functionsManager = new FunctionsManager(this); this.dataManager = new DataManager(this); - this.invalidateQueries = throttle( + const invalidateQueries = throttle( () => { this.events.emit('queriesInvalidated', {}); }, @@ -1054,6 +1047,9 @@ class ToolpadProject { leading: false, }, ); + + this.events.on('functionsChanged', invalidateQueries); + this.events.on('envChanged', invalidateQueries); } private initWatcher() { @@ -1353,17 +1349,6 @@ class ToolpadProject { return config; } - async getRuntimeConfig(): Promise { - // When these fail, you are likely trying to retrieve this information during the - // Toolpad Studio build. It's fundamentally wrong to use this information as it strictly holds - // information about the running Toolpad Studio instance. - invariant(this.options.externalUrl, 'External URL is not set'); - - return { - externalUrl: this.options.externalUrl, - }; - } - async writeBuildInfo() { await writeFileRecursive( this.getBuildInfoFile(), diff --git a/packages/toolpad-studio/src/server/projectRpcServer.ts b/packages/toolpad-studio/src/server/projectRpcServer.ts index c2d098dfdba..30fdbc17327 100644 --- a/packages/toolpad-studio/src/server/projectRpcServer.ts +++ b/packages/toolpad-studio/src/server/projectRpcServer.ts @@ -47,9 +47,6 @@ export function createRpcServer(project: ToolpadProject) { createDataProvider: createMethod(({ params }) => { return project.createDataProvider(...params); }), - getRuntimeConfig: createMethod(({ params }) => { - return project.getRuntimeConfig(...params); - }), getComponents: createMethod(({ params }) => { return project.getComponentsManifest(...params); }), diff --git a/packages/toolpad-studio/src/server/toolpadAppServer.ts b/packages/toolpad-studio/src/server/toolpadAppServer.ts index 6c7c242271b..ed0960454c8 100644 --- a/packages/toolpad-studio/src/server/toolpadAppServer.ts +++ b/packages/toolpad-studio/src/server/toolpadAppServer.ts @@ -8,28 +8,19 @@ import { asyncHandler } from '../utils/express'; import { basicAuthUnauthorized, checkBasicAuthHeader } from './basicAuth'; import { createRpcServer } from './runtimeRpcServer'; import { createRpcHandler } from './rpc'; -import { RUNTIME_CONFIG_WINDOW_PROPERTY, INITIAL_STATE_WINDOW_PROPERTY } from '../constants'; +import { INITIAL_STATE_WINDOW_PROPERTY } from '../constants'; import createRuntimeState from '../runtime/createRuntimeState'; -import type { RuntimeConfig } from '../types'; import type { RuntimeState } from '../runtime'; import { createAuthHandler, createRequireAuthMiddleware, getRequireAuthentication } from './auth'; export interface PostProcessHtmlParams { - config: RuntimeConfig; initialState: RuntimeState; } -export function postProcessHtml( - html: string, - { config, initialState }: PostProcessHtmlParams, -): string { - const serializedConfig = serializeJavascript(config, { ignoreFunction: true }); +export function postProcessHtml(html: string, { initialState }: PostProcessHtmlParams): string { const serializedInitialState = serializeJavascript(initialState, { isJSON: true }); const toolpadScripts = [ - ``, ``, @@ -80,15 +71,11 @@ export async function createProdHandler(project: ToolpadProject) { asyncHandler(async (req, res) => { const htmlFilePath = path.resolve(project.getAppOutputFolder(), './index.html'); - const [runtimeConfig, dom] = await Promise.all([ - project.getRuntimeConfig(), - project.loadDom(), - ]); + const [dom] = await Promise.all([project.loadDom()]); let html = await fs.readFile(htmlFilePath, { encoding: 'utf-8' }); html = postProcessHtml(html, { - config: runtimeConfig, initialState: createRuntimeState({ dom }), }); diff --git a/packages/toolpad-studio/src/toolpad/AppEditor/PageEditor/QueryEditor/QueryEditorPanel.tsx b/packages/toolpad-studio/src/toolpad/AppEditor/PageEditor/QueryEditor/QueryEditorPanel.tsx index c0ffc7ab29c..9d3a790b2bf 100644 --- a/packages/toolpad-studio/src/toolpad/AppEditor/PageEditor/QueryEditor/QueryEditorPanel.tsx +++ b/packages/toolpad-studio/src/toolpad/AppEditor/PageEditor/QueryEditor/QueryEditorPanel.tsx @@ -173,8 +173,6 @@ export default function QueryEditorPanel({ draft, saved }: QueryEditorProps) { const { dom } = useAppState(); const projectApi = useProjectApi(); - const { data: runtimeConfig } = projectApi.useSuspenseQuery('getRuntimeConfig', []); - const connectionId = appDom.deref(saved ? saved?.attributes?.connectionId : draft?.attributes?.connectionId) ?? null; @@ -216,7 +214,6 @@ export default function QueryEditorPanel({ draft, saved }: QueryEditorProps) { globalScope={pageState} globalScopeMeta={globalScopeMeta} execApi={execPrivate} - runtimeConfig={runtimeConfig} settingsTab={ { +export default function createDatasource(): ServerDataSource< + GoogleSheetsConnectionParams, + GoogleSheetsApiQuery, + GoogleSheetsPrivateQuery +> { /** * Executor function for this connection * @param connection The connection object @@ -74,8 +78,7 @@ export default function createDatasource( connection: Maybe, query: GoogleSheetsApiQuery, ): Promise => { - const runtimeConfig = await project.getRuntimeConfig(); - const client = createOAuthClient(runtimeConfig.externalUrl); + const client = createOAuthClient(); if (connection) { client.setCredentials(connection); } @@ -125,8 +128,7 @@ export default function createDatasource( connection: Maybe, query: GoogleSheetsPrivateQuery, ): Promise => { - const runtimeConfig = await project.getRuntimeConfig(); - const client = createOAuthClient(runtimeConfig.externalUrl); + const client = createOAuthClient(); if (connection) { client.setCredentials(connection); } @@ -218,8 +220,7 @@ export default function createDatasource( req: express.Request, res: express.Response, ): Promise => { - const runtimeConfig = await project.getRuntimeConfig(); - const client = createOAuthClient(runtimeConfig.externalUrl); + const client = createOAuthClient(); try { const pathname = `/${asArray(req.query.path) .map((segment = '') => encodeURIComponent(String(segment))) diff --git a/packages/toolpad-studio/src/toolpadDataSources/server.ts b/packages/toolpad-studio/src/toolpadDataSources/server.ts index 0eca22455e4..d8837336d6f 100644 --- a/packages/toolpad-studio/src/toolpadDataSources/server.ts +++ b/packages/toolpad-studio/src/toolpadDataSources/server.ts @@ -1,4 +1,4 @@ -import type { ServerDataSource, RuntimeConfig } from '../types'; +import type { ServerDataSource } from '../types'; import postgres from './postgres/server'; import mysql from './mysql/server'; import rest from './rest/server'; @@ -10,7 +10,6 @@ import type EnvManager from '../server/EnvManager'; export interface IToolpadProject { functionsManager: FunctionsManager; envManager: EnvManager; - getRuntimeConfig: () => Promise; } type ServerDataSources = { diff --git a/packages/toolpad-studio/src/types.ts b/packages/toolpad-studio/src/types.ts index 90bade098ef..c2c4487e152 100644 --- a/packages/toolpad-studio/src/types.ts +++ b/packages/toolpad-studio/src/types.ts @@ -16,12 +16,6 @@ import type * as appDom from '@toolpad/studio-runtime/appDom'; import type { Rectangle } from './utils/geometry'; import type { RuntimeState } from './runtime'; -// These are set at runtime and passed to the browser. -// Do not add secrets -export interface RuntimeConfig { - externalUrl: string; -} - declare global { interface Error { code?: unknown; @@ -104,7 +98,6 @@ export interface QueryEditorProps { settingsTab?: React.ReactNode; onChange?: React.Dispatch>>; onCommit?: () => void; - runtimeConfig: RuntimeConfig; } export type QueryEditor = React.FC>; @@ -202,7 +195,6 @@ export type ProjectEvents = { export interface ToolpadProjectOptions { toolpadDevMode: boolean; dev: boolean; - externalUrl?: string; base: string; customServer: boolean; } From 3661d4bb7e18f0d26aaa441d8d1c1cf40831c13a Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Tue, 30 Apr 2024 12:13:35 +0200 Subject: [PATCH 2/2] ret --- .../src/server/appServerWorker.ts | 17 +++++++---------- .../src/server/toolpadAppBuilder.ts | 9 +++++++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/toolpad-studio/src/server/appServerWorker.ts b/packages/toolpad-studio/src/server/appServerWorker.ts index e65946f7df7..4f4fdc0db26 100644 --- a/packages/toolpad-studio/src/server/appServerWorker.ts +++ b/packages/toolpad-studio/src/server/appServerWorker.ts @@ -26,14 +26,7 @@ invariant( 'The dev server must be started with NODE_ENV=development', ); -export interface ToolpadAppDevServerParams { - outDir: string; - root: string; - base: string; - customServer: boolean; -} - -function devServerPlugin({}: ToolpadAppDevServerParams): Plugin { +function devServerPlugin(): Plugin { return { name: 'toolpad-dev-server', @@ -62,7 +55,11 @@ function devServerPlugin({}: ToolpadAppDevServerParams): Plugin { }; } -export interface AppViteServerConfig extends ToolpadAppDevServerParams { +export interface AppViteServerConfig { + outDir: string; + root: string; + base: string; + customServer: boolean; toolpadDevMode: boolean; port: number; mainThreadRpcPort: MessagePort; @@ -72,7 +69,7 @@ export async function main({ port, ...config }: AppViteServerConfig) { const { reloadComponents, viteConfig } = await createViteConfig({ ...config, dev: true, - plugins: [devServerPlugin(config)], + plugins: [devServerPlugin()], getComponents, getPagesManifest, loadDom, diff --git a/packages/toolpad-studio/src/server/toolpadAppBuilder.ts b/packages/toolpad-studio/src/server/toolpadAppBuilder.ts index 052681b7995..37db1518339 100644 --- a/packages/toolpad-studio/src/server/toolpadAppBuilder.ts +++ b/packages/toolpad-studio/src/server/toolpadAppBuilder.ts @@ -140,6 +140,11 @@ export interface CreateViteConfigParams { getPagesManifest: () => Promise; } +export interface CreateViteConfigResult { + reloadComponents: () => Promise; + viteConfig: InlineConfig; +} + export async function createViteConfig({ toolpadDevMode, outDir, @@ -151,7 +156,7 @@ export async function createViteConfig({ getComponents, loadDom, getPagesManifest, -}: CreateViteConfigParams) { +}: CreateViteConfigParams): Promise { const mode = dev ? 'development' : 'production'; const initialDom = await loadDom(); @@ -398,7 +403,7 @@ if (import.meta.hot) { 'process.env.TOOLPAD_BUILD': JSON.stringify(TOOLPAD_BUILD), 'process.env.TOOLPAD_PLAN': JSON.stringify(plan), }, - } satisfies InlineConfig, + }, }; }