From 3a1eeada790a67eae52b9543c39bccbc26e062f3 Mon Sep 17 00:00:00 2001 From: Tom Meagher Date: Wed, 13 Mar 2024 11:48:37 -0400 Subject: [PATCH] chore: tweaks --- .gitignore | 1 - .scripts/postbuild.ts | 38 +---------- playground/package.json | 1 + playground/src/index.tsx | 3 +- pnpm-lock.yaml | 59 +++++++++++----- src/dev/client.tsx | 144 --------------------------------------- src/dev/client_.tsx | 32 --------- src/dev/devtools.ts | 36 ---------- src/dev/devtools.tsx | 131 +++++++++++++++++++++++++++++++++++ src/package.json | 1 + src/types/utils.ts | 2 + ui/src/App.css | 13 +--- ui/src/App.tsx | 16 ++++- ui/src/assets/react.svg | 1 + ui/src/assets/vite.svg | 1 + ui/src/index.css | 54 --------------- ui/vite.config.ts | 2 +- 17 files changed, 200 insertions(+), 335 deletions(-) delete mode 100644 src/dev/client.tsx delete mode 100644 src/dev/client_.tsx delete mode 100644 src/dev/devtools.ts create mode 100644 src/dev/devtools.tsx create mode 100644 ui/src/assets/react.svg create mode 100644 ui/src/assets/vite.svg diff --git a/.gitignore b/.gitignore index f82fdc29..058e740e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,5 @@ coverage create-frog/templates node_modules site/dist -src/dev/ui tsconfig.*.tsbuildinfo tsconfig.tsbuildinfo diff --git a/.scripts/postbuild.ts b/.scripts/postbuild.ts index b2bddbde..f155a4ae 100644 --- a/.scripts/postbuild.ts +++ b/.scripts/postbuild.ts @@ -1,44 +1,10 @@ -import { resolve, extname } from 'node:path' +import { resolve } from 'node:path' import glob from 'fast-glob' -import { copy, rename, remove } from 'fs-extra' +import { copy, rename } from 'fs-extra' -await inlineDevtoolsStaticFiles() await rewriteHonoJsx() await prepareTemplates() -async function inlineDevtoolsStaticFiles() { - const assetPaths = [ - ...(await glob('./src/dev/ui/assets/*')), - './src/dev/ui/index.js', - ] - const content: string[] = [] - for (const asset of assetPaths) { - const file = await Bun.file(asset).text() - const escaped = file.trim().replace(/"/g, '\\"') - - const extension = extname(asset) - if (extension === '.css') - content.push(`_jsx("style", { children: "${escaped}" })`) - else if (extension === '.js') - content.push( - `_jsx("script", { children: html("${escaped}"), type: "module" })`, - ) - else throw new Error(`Unknown asset type: ${extension}`) - } - - const entryPath = './src/_lib/dev/client_.js' - let entry = await Bun.file(entryPath).text() - entry = entry.replace('_jsx(_Fragment, {})', content.join(', ')) - - await Bun.write('./src/_lib/dev/client_.js', entry) - - const renameClientPaths = await glob('./src/_lib/dev/client_.*') - for (const path of renameClientPaths) - await rename(path, path.replace('client_', 'client')) - - await remove('./src/dev/ui') -} - async function rewriteHonoJsx() { const files = await glob('./src/_lib/**/*.js') for (const file of files) { diff --git a/playground/package.json b/playground/package.json index 4fbe4700..16065f7d 100644 --- a/playground/package.json +++ b/playground/package.json @@ -6,6 +6,7 @@ "dev": "node --import tsx ../src/cli/index.ts" }, "dependencies": { + "@hono/node-server": "^1.8.2", "frog": "workspace:*", "hono": "^4" }, diff --git a/playground/src/index.tsx b/playground/src/index.tsx index f2d409f3..73ae0da8 100644 --- a/playground/src/index.tsx +++ b/playground/src/index.tsx @@ -1,6 +1,7 @@ import { Button, Frog, TextInput } from 'frog' import * as hubs from 'frog/hubs' import { devtools } from 'frog/dev' +import { serveStatic } from '@hono/node-server/serve-static' import { app as middlewareApp } from './middleware.js' import { app as neynarApp } from './neynar.js' @@ -234,4 +235,4 @@ app.route('/routing', routingApp) app.route('/transaction', transactionApp) app.route('/todos', todoApp) -devtools(app) +devtools(app, { serveStatic }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8148d78b..6b4182dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -89,6 +89,9 @@ importers: playground: dependencies: + '@hono/node-server': + specifier: ^1.8.2 + version: 1.8.2 frog: specifier: workspace:* version: link:../src @@ -132,7 +135,7 @@ importers: dependencies: frog: specifier: latest - version: 0.5.7(@types/node@14.18.33)(hono@4.1.0)(typescript@4.9.5) + version: 0.5.8(@types/node@14.18.33)(hono@4.1.0)(typescript@4.9.5) hono: specifier: ^4.1.0 version: 4.1.0 @@ -151,7 +154,7 @@ importers: version: 18.2.57 frog: specifier: latest - version: 0.5.7(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) + version: 0.5.8(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) react: specifier: latest version: 18.2.0 @@ -170,6 +173,9 @@ importers: '@bufbuild/protobuf': specifier: ^1.7.2 version: 1.7.2 + '@hono/node-server': + specifier: ^1.8.2 + version: 1.8.2 '@hono/vite-dev-server': specifier: 0.7.0 version: 0.7.0(hono@4.1.0) @@ -223,7 +229,7 @@ importers: dependencies: frog: specifier: latest - version: 0.5.7(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) + version: 0.5.8(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) hono: specifier: ^4.1.0 version: 4.1.0 @@ -239,7 +245,7 @@ importers: dependencies: frog: specifier: latest - version: 0.5.7(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) + version: 0.5.8(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) hono: specifier: ^4.1.0 version: 4.1.0 @@ -255,7 +261,7 @@ importers: version: 1.8.2 frog: specifier: latest - version: 0.5.7(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) + version: 0.5.8(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) hono: specifier: ^4.1.0 version: 4.1.0 @@ -268,7 +274,7 @@ importers: dependencies: frog: specifier: latest - version: 0.5.7(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) + version: 0.5.8(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) hono: specifier: ^4.1.0 version: 4.1.0 @@ -302,7 +308,7 @@ importers: version: 1.8.1 frog: specifier: latest - version: 0.5.7(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) + version: 0.5.8(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3) hono: specifier: ^4.1.0 version: 4.1.0 @@ -318,7 +324,7 @@ importers: dependencies: frog: specifier: latest - version: 0.5.7(@types/node@14.18.33)(hono@4.1.0)(typescript@5.3.3) + version: 0.5.8(@types/node@14.18.33)(hono@4.1.0)(typescript@5.3.3) hono: specifier: ^4.1.0 version: 4.1.0 @@ -5813,8 +5819,8 @@ packages: engines: {node: '>= 0.6'} dev: false - /frog@0.5.7(@types/node@14.18.33)(hono@4.1.0)(typescript@4.9.5): - resolution: {integrity: sha512-6PySAMU45J/fIGyhiOmm2+6rSpUC/eD87b6MndBo/+CeJ+k4w/B9jGY34zUiq0xT4fRDCrH61YYggP8INaSaFw==} + /frog@0.5.8(@types/node@14.18.33)(hono@4.1.0)(typescript@4.9.5): + resolution: {integrity: sha512-53/fBzfXpAp/eh8uunKHIw+ohu+Eb+jAkeoDe1GgKvARdH3Nhd1vInDmRRu77nNquj099zkk67hYg/0eVSYaXw==} hasBin: true peerDependencies: hono: ^4.1.0 @@ -5834,7 +5840,7 @@ packages: fast-glob: 3.3.2 fs-extra: 11.2.0 hono: 4.1.0 - hono-og: 0.0.22(hono@4.1.0) + hono-og: 0.0.24(hono@4.1.0) jose: 5.2.2 lz-string: 1.5.0 path-browserify: 1.0.1 @@ -5856,8 +5862,8 @@ packages: - zod dev: false - /frog@0.5.7(@types/node@14.18.33)(hono@4.1.0)(typescript@5.3.3): - resolution: {integrity: sha512-6PySAMU45J/fIGyhiOmm2+6rSpUC/eD87b6MndBo/+CeJ+k4w/B9jGY34zUiq0xT4fRDCrH61YYggP8INaSaFw==} + /frog@0.5.8(@types/node@14.18.33)(hono@4.1.0)(typescript@5.3.3): + resolution: {integrity: sha512-53/fBzfXpAp/eh8uunKHIw+ohu+Eb+jAkeoDe1GgKvARdH3Nhd1vInDmRRu77nNquj099zkk67hYg/0eVSYaXw==} hasBin: true peerDependencies: hono: ^4.1.0 @@ -5877,7 +5883,7 @@ packages: fast-glob: 3.3.2 fs-extra: 11.2.0 hono: 4.1.0 - hono-og: 0.0.22(hono@4.1.0) + hono-og: 0.0.24(hono@4.1.0) jose: 5.2.2 lz-string: 1.5.0 path-browserify: 1.0.1 @@ -5899,8 +5905,8 @@ packages: - zod dev: false - /frog@0.5.7(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3): - resolution: {integrity: sha512-6PySAMU45J/fIGyhiOmm2+6rSpUC/eD87b6MndBo/+CeJ+k4w/B9jGY34zUiq0xT4fRDCrH61YYggP8INaSaFw==} + /frog@0.5.8(@types/node@20.11.19)(hono@4.1.0)(typescript@5.3.3): + resolution: {integrity: sha512-53/fBzfXpAp/eh8uunKHIw+ohu+Eb+jAkeoDe1GgKvARdH3Nhd1vInDmRRu77nNquj099zkk67hYg/0eVSYaXw==} hasBin: true peerDependencies: hono: ^4.1.0 @@ -5920,7 +5926,7 @@ packages: fast-glob: 3.3.2 fs-extra: 11.2.0 hono: 4.1.0 - hono-og: 0.0.22(hono@4.1.0) + hono-og: 0.0.24(hono@4.1.0) jose: 5.2.2 lz-string: 1.5.0 path-browserify: 1.0.1 @@ -6389,6 +6395,16 @@ packages: workers-og: 0.0.20 dev: false + /hono-og@0.0.24(hono@4.1.0): + resolution: {integrity: sha512-V+npyPvqlfuJ3A7UEfCjs7ZdZ9380KsYPQ+Y1dmQ0+NKkrpeTQbDQELptVkbOJH7Pi+m+RQLRLyqOzbSKyOZ9Q==} + peerDependencies: + hono: ^4.1.0 + dependencies: + '@vercel/og': 0.6.2 + hono: 4.1.0 + workers-og: 0.0.23 + dev: false + /hono@4.1.0: resolution: {integrity: sha512-9no6DCHb4ijB1tWdFXU6JnrnFgzwVZ1cnIcS1BjAFnMcjbtBTOMsQrDrPH3GXbkNEEEkj8kWqcYBy8Qc0bBkJQ==} engines: {node: '>=16.0.0'} @@ -10579,6 +10595,15 @@ packages: yoga-wasm-web: 0.3.3 dev: false + /workers-og@0.0.23: + resolution: {integrity: sha512-caVuk/muVgLwc0frelrrIxvSUhkRRrPNeHCh4psy6l6MPTngCkDXxqIHOTG/b54NvCCC57T+uobohDO0Se54xw==} + dependencies: + '@resvg/resvg-wasm': 2.4.0 + just-camel-case: 6.2.0 + satori: 0.10.13 + yoga-wasm-web: 0.3.3 + dev: false + /wrangler@3.29.0: resolution: {integrity: sha512-VXUUltM0/fxCF20Z3tH39zpnykDJNPH2lMWI5wA0VmRpuKG0Gffjj5lU2vJaI/PfUCo3q4JErxWcgLezBGnFyA==} engines: {node: '>=16.17.0'} diff --git a/src/dev/client.tsx b/src/dev/client.tsx deleted file mode 100644 index 81d000ce..00000000 --- a/src/dev/client.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import { createReadStream, existsSync, lstatSync } from 'fs' -import type { ReadStream } from 'fs' -import { fileURLToPath } from 'node:url' -import { Hono } from 'hono' -import type { Context, MiddlewareHandler } from 'hono' -import { getFilePath } from 'hono/utils/filepath' -import { getMimeType } from 'hono/utils/mime' -import { resolve, dirname, relative } from 'path' -import { html } from 'hono/html' - -export type ClientRouteOptions = { - basePath: string -} - -export function clientRoutes(options: ClientRouteOptions) { - return new Hono() - .get('/', async (c) => { - return c.html( - - - - - frog - - - - - - <>{/*--client-outlet--*/} - - -
- - , - ) - }) -} diff --git a/src/dev/devtools.ts b/src/dev/devtools.ts deleted file mode 100644 index c37e2a82..00000000 --- a/src/dev/devtools.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { type Schema } from 'hono' -import { inspectRoutes } from 'hono/dev' - -import type { FrogBase } from '../frog-base.js' -import type { Env } from '../types/env.js' -import { apiRoutes, type ApiRoutesOptions } from './api.js' -import type { Pretty } from '../types/utils.js' -import { clientRoutes } from './client.js' - -export type DevtoolsOptions = Pretty - -export function devtools< - env extends Env, - schema extends Schema, - basePath extends string, - // - state = env['State'], ->(frog: FrogBase, options: DevtoolsOptions = {}) { - const { appFid, appMnemonic } = options - - frog.hono - .route( - '/dev', - clientRoutes({ - basePath: frog.basePath, - }), - ) - .route( - '/dev/api', - apiRoutes({ - appFid, - appMnemonic, - routes: inspectRoutes(frog.hono), - }), - ) -} diff --git a/src/dev/devtools.tsx b/src/dev/devtools.tsx new file mode 100644 index 00000000..c1726bd5 --- /dev/null +++ b/src/dev/devtools.tsx @@ -0,0 +1,131 @@ +import { Hono, type Schema } from 'hono' +import { inspectRoutes } from 'hono/dev' +import type { serveStatic as n_serveStatic } from '@hono/node-server/serve-static' +import type { serveStatic as c_serveStatic } from 'hono/cloudflare-workers' +import type { serveStatic as b_serveStatic } from 'hono/bun' +import { dirname, relative, resolve } from 'path' +import { fileURLToPath } from 'url' +import { html } from 'hono/html' + +import type { FrogBase } from '../frog-base.js' +import type { Env } from '../types/env.js' +import { apiRoutes, type ApiRoutesOptions } from './api.js' +import type { Pretty } from '../types/utils.js' + +export type DevtoolsOptions = Pretty< + Pretty & { + assetsPath?: string + /** + * The base path for the devtools instance. + * + * @default '/dev' + */ + basePath?: string | undefined + serveStatic?: ServeStatic | undefined + serveStaticOptions?: + | Pretty< + Omit< + Pretty[0]>>, + 'rewriteRequestPath' | 'root' + > + > + | undefined + } +> + +type ServeStatic = + | typeof n_serveStatic + | typeof c_serveStatic + | typeof b_serveStatic + +export function devtools< + env extends Env, + schema extends Schema, + basePath extends string, + /// + state = env['State'], +>(frog: FrogBase, options: DevtoolsOptions) { + const { + appFid, + appMnemonic, + assetsPath, + basePath = '/dev', + serveStatic, + serveStaticOptions = { manifest: '' }, + } = options + + const app = new Hono() + let publicPath = '' + if (assetsPath) publicPath = assetsPath === '/' ? '' : assetsPath + else if (serveStatic) publicPath = `.${basePath}` + else publicPath = frog.assetsPath === '/' ? '' : frog.assetsPath + + // TODO: + // - vercel-build output to public dir (works with `publicPath`) + // - rewrite `@hono/vite-dev-server` (`@vite/client` to frames, `frog-client` to devtools) + // - middleware? + + app + .get('/', (c) => { + return c.html( + <> + {html``} + + + + + frog + + + +