diff --git a/.scripts/postbuild.ts b/.scripts/postbuild.ts index 279d79cf..f155a4ae 100644 --- a/.scripts/postbuild.ts +++ b/.scripts/postbuild.ts @@ -1,49 +1,10 @@ -import { resolve, extname } from 'node:path' +import { resolve } from 'node:path' import glob from 'fast-glob' import { copy, rename } from 'fs-extra' -// await inlineDevtoolsStaticFiles() await rewriteHonoJsx() await prepareTemplates() -async function inlineDevtoolsStaticFiles() { - const assetPaths = [ - ...(await glob('./src/_lib/dev/static/assets/*')), - './src/_lib/dev/static/entry-client.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}`) - } - - console.log(content) - - const entryPath = './src/_lib/dev/entry-server.js' - const entry = await Bun.file(entryPath).text() - - // const escapedJs = js.trim().replace(/"/g, '\\"') - // const script = `_jsx("script", { children: html(\"${escapedJs}\"), type: "module", crossorigin: "" })` - // - // // https://regexr.com/7t4ee - // const scriptRegex = /, _jsx\(\"script\".*?\}\)/ - // const content = `import { html } from 'hono/html'\n${entry.replace( - // scriptRegex, - // `, ${style}, ${script}`, - // )}` - // - // await Bun.write('./src/_lib/dev/entry-server.js', content) -} - async function rewriteHonoJsx() { const files = await glob('./src/_lib/**/*.js') for (const file of files) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0fc130f..494c0319 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -131,7 +131,7 @@ importers: dependencies: frog: specifier: latest - version: link:../../src + version: 0.5.0(@types/node@14.18.33)(hono@4.0.9)(typescript@4.9.5) hono: specifier: 4.0.9 version: 4.0.9 @@ -150,7 +150,7 @@ importers: version: 18.2.57 frog: specifier: latest - version: link:../src + version: 0.5.0(@types/node@20.11.19)(hono@4.0.9)(typescript@5.3.3) react: specifier: latest version: 18.2.0 @@ -237,7 +237,7 @@ importers: dependencies: frog: specifier: latest - version: link:../../src + version: 0.5.0(@types/node@20.11.19)(hono@4.0.9)(typescript@5.3.3) hono: specifier: 4.0.9 version: 4.0.9 @@ -253,7 +253,7 @@ importers: dependencies: frog: specifier: latest - version: link:../../src + version: 0.5.0(@types/node@20.11.19)(hono@4.0.9)(typescript@5.3.3) hono: specifier: 4.0.9 version: 4.0.9 @@ -269,7 +269,7 @@ importers: version: 1.8.2 frog: specifier: latest - version: link:../../src + version: 0.5.0(@types/node@20.11.19)(hono@4.0.9)(typescript@5.3.3) hono: specifier: 4.0.9 version: 4.0.9 @@ -282,7 +282,7 @@ importers: dependencies: frog: specifier: latest - version: link:../../src + version: 0.5.0(@types/node@20.11.19)(hono@4.0.9)(typescript@5.3.3) hono: specifier: 4.0.9 version: 4.0.9 @@ -316,7 +316,7 @@ importers: version: 1.8.1 frog: specifier: latest - version: link:../../src + version: 0.5.0(@types/node@20.11.19)(hono@4.0.9)(typescript@5.3.3) hono: specifier: 4.0.9 version: 4.0.9 @@ -332,7 +332,7 @@ importers: dependencies: frog: specifier: latest - version: link:../../src + version: 0.5.0(@types/node@14.18.33)(hono@4.0.9)(typescript@5.3.3) hono: specifier: 4.0.9 version: 4.0.9 @@ -1765,6 +1765,23 @@ packages: requiresBuild: true optional: true + /@farcaster/core@0.13.8(typescript@4.9.5): + resolution: {integrity: sha512-h1WU5IinBwy8f5mGqyAQGxBGuCFPj+kYt/OQquE+898bdlU7LibwsAi2P2qD6Fkb+0GmqloF4m7DIg68wfpfWw==} + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + ffi-napi: 4.0.3 + neverthrow: 6.1.0 + ref-napi: 3.0.3 + viem: 1.21.4(typescript@4.9.5) + transitivePeerDependencies: + - bufferutil + - supports-color + - typescript + - utf-8-validate + - zod + dev: false + /@farcaster/core@0.13.8(typescript@5.3.3): resolution: {integrity: sha512-h1WU5IinBwy8f5mGqyAQGxBGuCFPj+kYt/OQquE+898bdlU7LibwsAi2P2qD6Fkb+0GmqloF4m7DIg68wfpfWw==} dependencies: @@ -3352,7 +3369,6 @@ packages: /@types/node@14.18.33: resolution: {integrity: sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==} - dev: true /@types/node@20.11.19: resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==} @@ -3915,10 +3931,33 @@ packages: yoga-wasm-web: 0.3.3 dev: false + /@wevm/vercel-og@0.6.12: + resolution: {integrity: sha512-gaFbJR7fV7oFega1/8omhpp/cTHWpZkFpuiIaevDil6HroQYhX1RBFNse3uYeSbnhb3pHnAm85tjYuOi/wB6EQ==} + engines: {node: '>=16'} + dependencies: + '@resvg/resvg-wasm': 2.4.0 + satori: 0.10.9 + yoga-wasm-web: 0.3.3 + dev: false + /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: true + /abitype@0.9.8(typescript@4.9.5): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 4.9.5 + dev: false + /abitype@0.9.8(typescript@5.3.3): resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} peerDependencies: @@ -5722,6 +5761,138 @@ packages: engines: {node: '>= 0.6'} dev: false + /frog@0.5.0(@types/node@14.18.33)(hono@4.0.9)(typescript@4.9.5): + resolution: {integrity: sha512-P4JOYrkBmp2n1Gd7BiHuAHCxlEN8eKR/AaOlXC3SAxNJRE/GGJ52k/QpE6No++K1tI6IbKCAnV0gw6bXo3iYzQ==} + hasBin: true + peerDependencies: + hono: 4.0.9 + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@bufbuild/protobuf': 1.7.2 + '@farcaster/core': 0.13.8(typescript@4.9.5) + '@hono/vite-dev-server': 0.7.0(hono@4.0.9) + '@ngrok/ngrok': 1.1.0 + '@noble/curves': 1.3.0 + cac: 6.7.14 + detect-browser: 5.3.0 + dom-parser: 1.1.5 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + happy-dom: 13.3.8 + hono: 4.0.9 + hono-og: 0.0.22(hono@4.0.9) + jose: 5.2.2 + lz-string: 1.5.0 + path-browserify: 1.0.1 + qrcode: 1.5.3 + typescript: 4.9.5 + viem: 2.7.11(typescript@4.9.5) + vite: 5.1.3(@types/node@14.18.33) + transitivePeerDependencies: + - '@types/node' + - bufferutil + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - utf-8-validate + - zod + dev: false + + /frog@0.5.0(@types/node@14.18.33)(hono@4.0.9)(typescript@5.3.3): + resolution: {integrity: sha512-P4JOYrkBmp2n1Gd7BiHuAHCxlEN8eKR/AaOlXC3SAxNJRE/GGJ52k/QpE6No++K1tI6IbKCAnV0gw6bXo3iYzQ==} + hasBin: true + peerDependencies: + hono: 4.0.9 + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@bufbuild/protobuf': 1.7.2 + '@farcaster/core': 0.13.8(typescript@5.3.3) + '@hono/vite-dev-server': 0.7.0(hono@4.0.9) + '@ngrok/ngrok': 1.1.0 + '@noble/curves': 1.3.0 + cac: 6.7.14 + detect-browser: 5.3.0 + dom-parser: 1.1.5 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + happy-dom: 13.3.8 + hono: 4.0.9 + hono-og: 0.0.22(hono@4.0.9) + jose: 5.2.2 + lz-string: 1.5.0 + path-browserify: 1.0.1 + qrcode: 1.5.3 + typescript: 5.3.3 + viem: 2.7.11(typescript@5.3.3) + vite: 5.1.3(@types/node@14.18.33) + transitivePeerDependencies: + - '@types/node' + - bufferutil + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - utf-8-validate + - zod + dev: false + + /frog@0.5.0(@types/node@20.11.19)(hono@4.0.9)(typescript@5.3.3): + resolution: {integrity: sha512-P4JOYrkBmp2n1Gd7BiHuAHCxlEN8eKR/AaOlXC3SAxNJRE/GGJ52k/QpE6No++K1tI6IbKCAnV0gw6bXo3iYzQ==} + hasBin: true + peerDependencies: + hono: 4.0.9 + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@bufbuild/protobuf': 1.7.2 + '@farcaster/core': 0.13.8(typescript@5.3.3) + '@hono/vite-dev-server': 0.7.0(hono@4.0.9) + '@ngrok/ngrok': 1.1.0 + '@noble/curves': 1.3.0 + cac: 6.7.14 + detect-browser: 5.3.0 + dom-parser: 1.1.5 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + happy-dom: 13.3.8 + hono: 4.0.9 + hono-og: 0.0.22(hono@4.0.9) + jose: 5.2.2 + lz-string: 1.5.0 + path-browserify: 1.0.1 + qrcode: 1.5.3 + typescript: 5.3.3 + viem: 2.7.11(typescript@5.3.3) + vite: 5.1.3(@types/node@20.11.19) + transitivePeerDependencies: + - '@types/node' + - bufferutil + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - utf-8-validate + - zod + dev: false + /fs-extra@11.1.0: resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} engines: {node: '>=14.14'} @@ -6188,6 +6359,17 @@ packages: workers-og: 0.0.20 dev: false + /hono-og@0.0.22(hono@4.0.9): + resolution: {integrity: sha512-fq04Nhhbtyto4WL8r9+ozUB9e0PKUD/G+bdI7+NkU7+H4ZqkiTjTSAg94FDq1Kdz9Bql4ZaqyOkGo7cmVFo84g==} + peerDependencies: + hono: 4.0.9 + dependencies: + '@vercel/og': 0.6.2 + '@wevm/vercel-og': 0.6.12 + hono: 4.0.9 + workers-og: 0.0.20 + dev: false + /hono@4.0.9: resolution: {integrity: sha512-XkFx6y6jAl08bGmoy53oGtHl8eHUixvmBulfcghrSySoJD3cW4UfFUa7JDGLOsIeJUv/a9d2pBFQUX7rzRnjvA==} engines: {node: '>=16.0.0'} @@ -8303,6 +8485,17 @@ packages: yargs: 15.4.1 dev: false + /qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + dev: false + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -9971,6 +10164,29 @@ packages: vfile-message: 4.0.2 dev: false + /viem@1.21.4(typescript@4.9.5): + resolution: {integrity: sha512-BNVYdSaUjeS2zKQgPs+49e5JKocfo60Ib2yiXOWBT6LuVxY1I/6fFX3waEtpXvL1Xn4qu+BVitVtMh9lyThyhQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.9.8(typescript@4.9.5) + isows: 1.0.3(ws@8.13.0) + typescript: 4.9.5 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: false + /viem@1.21.4(typescript@5.3.3): resolution: {integrity: sha512-BNVYdSaUjeS2zKQgPs+49e5JKocfo60Ib2yiXOWBT6LuVxY1I/6fFX3waEtpXvL1Xn4qu+BVitVtMh9lyThyhQ==} peerDependencies: @@ -10060,6 +10276,42 @@ packages: - supports-color - terser + /vite@5.1.3(@types/node@14.18.33): + resolution: {integrity: sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 14.18.33 + esbuild: 0.19.12 + postcss: 8.4.35 + rollup: 4.12.0 + optionalDependencies: + fsevents: 2.3.3 + dev: false + /vite@5.1.3(@types/node@20.11.19): resolution: {integrity: sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew==} engines: {node: ^18.0.0 || >=20.0.0} diff --git a/src/dev/lib/context.tsx b/src/dev/Context.tsx similarity index 95% rename from src/dev/lib/context.tsx rename to src/dev/Context.tsx index 82b58554..d91e9d0d 100644 --- a/src/dev/lib/context.tsx +++ b/src/dev/Context.tsx @@ -1,10 +1,9 @@ import { type PropsWithChildren, createContext } from 'hono/jsx' import { useEffect, useState } from 'hono/jsx/dom' +import lz from 'lz-string' -import { LZString } from './lz-string.js' - -import { parsePath } from '../../utils/parsePath.js' -import { toSearchParams } from '../../utils/toSearchParams.js' +import { parsePath } from '../utils/parsePath.js' +import { toSearchParams } from '../utils/toSearchParams.js' import { type BaseData, type Data, @@ -12,7 +11,7 @@ import { type InitialData, type RequestBody, type User, -} from '../types.js' +} from './types.js' export const dataId = '__FROG_DATA__' @@ -82,7 +81,7 @@ export type DispatchValue = { export const DispatchContext = createContext({} as DispatchValue) -export type Props = PropsWithChildren<{ +export type ProviderProps = PropsWithChildren<{ data: BaseData & InitialData routes: readonly string[] user?: User | null | undefined @@ -90,7 +89,7 @@ export type Props = PropsWithChildren<{ let mounted = false -export function Provider(props: Props) { +export function Provider(props: ProviderProps) { const { children, data: initialData, routes, user } = props const { id: initialDataKey } = initialData @@ -99,11 +98,11 @@ export function Provider(props: Props) { if (typeof window !== 'undefined') { const state = location.hash.replace('#state/', '').trim() try { - let restored = LZString.decompressFromEncodedURIComponent(state) + let restored = lz.decompressFromEncodedURIComponent(state) // Fallback incase there is an extra level of decoding: // https://gitter.im/Microsoft/TypeScript?at=5dc478ab9c39821509ff189a if (!restored) - restored = LZString.decompressFromEncodedURIComponent( + restored = lz.decompressFromEncodedURIComponent( decodeURIComponent(state), ) @@ -343,7 +342,7 @@ export function Provider(props: Props) { // save partial state useEffect(() => { if (!mounted) return - const compressed = LZString.compressToEncodedURIComponent( + const compressed = lz.compressToEncodedURIComponent( JSON.stringify({ dataKey: state.dataKey, dataMap: state.dataMap, diff --git a/src/dev/components/Preview.tsx b/src/dev/components/Preview.tsx index f670f9a3..da7316cd 100644 --- a/src/dev/components/Preview.tsx +++ b/src/dev/components/Preview.tsx @@ -3,7 +3,7 @@ import { useRef, useState as useLocalState } from 'hono/jsx/dom' import { useDispatch } from '../hooks/useDispatch.js' import { useFocusTrap } from '../hooks/useFocusTrap.js' import { useState } from '../hooks/useState.js' -import { clsx } from '../lib/clsx.js' +import { clsx } from '../vendor/clsx.js' import { type Frame } from '../types.js' import { externalLinkIcon, half2Icon, warpIcon } from './icons.js' diff --git a/src/dev/components/Tabs.tsx b/src/dev/components/Tabs.tsx index b169aece..3ad8770a 100644 --- a/src/dev/components/Tabs.tsx +++ b/src/dev/components/Tabs.tsx @@ -1,7 +1,7 @@ import { useCopyToClipboard } from '../hooks/useCopyToClipboard.js' import { useDispatch } from '../hooks/useDispatch.js' import { useState as useGlobalState } from '../hooks/useState.js' -import { clsx } from '../lib/clsx.js' +import { clsx } from '../vendor//clsx.js' import { type Data, type Frame } from '../types.js' import { formatFileSize, formatSpeed } from '../utils/format.js' import { CodeToHtml } from './CodeToHtml.js' diff --git a/src/dev/components/Timeline.tsx b/src/dev/components/Timeline.tsx index 6fda97f6..9e85fc8f 100644 --- a/src/dev/components/Timeline.tsx +++ b/src/dev/components/Timeline.tsx @@ -1,11 +1,11 @@ import { useCallback, useRef, useState as useLocalState } from 'hono/jsx/dom' +import type { State } from '../Context.js' import { useDispatch } from '../hooks/useDispatch.js' import { useFocusTrap } from '../hooks/useFocusTrap.js' -import { clsx } from '../lib/clsx.js' -import type { State } from '../lib/context.js' import { type Data } from '../types.js' import { formatSpeed, formatTime } from '../utils/format.js' +import { clsx } from '../vendor/clsx.js' import { chevronDownIcon, chevronUpIcon, diff --git a/src/dev/constants.ts b/src/dev/constants.ts new file mode 100644 index 00000000..65e65c69 --- /dev/null +++ b/src/dev/constants.ts @@ -0,0 +1 @@ +export const staticPath = '/dev/static' diff --git a/src/dev/entry-client.tsx b/src/dev/entry-client.tsx index b6c8593a..1a071ea8 100644 --- a/src/dev/entry-client.tsx +++ b/src/dev/entry-client.tsx @@ -1,7 +1,7 @@ import { render } from 'hono/jsx/dom' import { App } from './App.js' -import { Provider, dataId } from './lib/context.js' +import { Provider, dataId } from './Context.js' import './styles.css' diff --git a/src/dev/entry-server.tsx b/src/dev/entry-server.tsx index 9cebaa8e..cbb997d1 100644 --- a/src/dev/entry-server.tsx +++ b/src/dev/entry-server.tsx @@ -1,42 +1,64 @@ +import { html } from 'hono/html' import { App } from './App.js' -import { Provider, type Props, dataId } from './lib/context.js' +import { staticPath } from './constants.js' +import { Provider, type ProviderProps, dataId } from './Context.js' type EntryServer = { path: string - providerProps: Props + providerProps: ProviderProps } export function EntryServer(props: EntryServer) { const { path, providerProps } = props return ( - - - frame: {path || '/'} - - + <> + {html``} + + + frame: {path || '/'} + + - {/* Inlined during build */} -