mirror of
https://github.com/tale/headplane.git
synced 2026-07-26 07:48:14 +00:00
feat: bundle all node_modules to reduce size
This commit is contained in:
@@ -8,5 +8,4 @@ app/hp_ssh.wasm
|
||||
app/wasm_exec.js
|
||||
/docs/.vitepress/dist/
|
||||
/docs/.vitepress/cache/
|
||||
|
||||
/.direnv
|
||||
|
||||
@@ -35,6 +35,7 @@ COPY --from=go-build /build/app/wasm_exec.js /build/app/wasm_exec.js
|
||||
ARG IMAGE_TAG
|
||||
RUN IMAGE_TAG=$IMAGE_TAG pnpm run build
|
||||
RUN mkdir -p /var/lib/headplane/agent
|
||||
RUN pnpm prune --prod
|
||||
|
||||
FROM gcr.io/distroless/nodejs22-debian12:latest AS final
|
||||
COPY --from=js-build /build/build/ /app/build/
|
||||
|
||||
+42
-40
@@ -11,7 +11,6 @@ import {
|
||||
useLoaderData,
|
||||
useSubmit,
|
||||
} from 'react-router';
|
||||
import wasm from '~/hp_ssh.wasm?url';
|
||||
import { LoadContext } from '~/server';
|
||||
import { EphemeralNodeInsert, ephemeralNodes } from '~/server/db/schema';
|
||||
import { Machine, PreAuthKey, User } from '~/types';
|
||||
@@ -215,46 +214,49 @@ export default function Page() {
|
||||
|
||||
pause();
|
||||
const go = new Go(); // Go is defined by wasm_exec.js
|
||||
WebAssembly.instantiateStreaming(fetch(wasm), go.importObject).then(
|
||||
(value) => {
|
||||
go.run(value.instance);
|
||||
const handle = TsWasmNet(ipnDetails, {
|
||||
NotifyState: (state) => {
|
||||
console.log('State changed:', state);
|
||||
if (state === 'Running') {
|
||||
setIpn(handle);
|
||||
}
|
||||
},
|
||||
NotifyNetMap: (netmap) => {
|
||||
// Only set NodeKey if it is not already set and then
|
||||
// also dispatch that to the backend to track the
|
||||
// ephemeral node.
|
||||
//
|
||||
// We open an SSE connection to the backend
|
||||
// so that when the connection is closed,
|
||||
// the backend can delete the ephemeral node.
|
||||
if (nodeKey === null) {
|
||||
setNodeKey(netmap.NodeKey);
|
||||
submit(
|
||||
{
|
||||
node_key: netmap.NodeKey,
|
||||
auth_key: ipnDetails.PreAuthKey,
|
||||
},
|
||||
{ method: 'POST' },
|
||||
);
|
||||
}
|
||||
},
|
||||
NotifyBrowseToURL: (url) => {
|
||||
console.log('Browse to URL:', url);
|
||||
},
|
||||
NotifyPanicRecover: (message) => {
|
||||
console.error('Panic recover:', message);
|
||||
},
|
||||
});
|
||||
|
||||
handle.Start();
|
||||
},
|
||||
);
|
||||
import('~/hp_ssh.wasm?url').then(({ default: url }) => {
|
||||
WebAssembly.instantiateStreaming(fetch(url), go.importObject).then(
|
||||
(value) => {
|
||||
go.run(value.instance);
|
||||
const handle = TsWasmNet(ipnDetails, {
|
||||
NotifyState: (state) => {
|
||||
console.log('State changed:', state);
|
||||
if (state === 'Running') {
|
||||
setIpn(handle);
|
||||
}
|
||||
},
|
||||
NotifyNetMap: (netmap) => {
|
||||
// Only set NodeKey if it is not already set and then
|
||||
// also dispatch that to the backend to track the
|
||||
// ephemeral node.
|
||||
//
|
||||
// We open an SSE connection to the backend
|
||||
// so that when the connection is closed,
|
||||
// the backend can delete the ephemeral node.
|
||||
if (nodeKey === null) {
|
||||
setNodeKey(netmap.NodeKey);
|
||||
submit(
|
||||
{
|
||||
node_key: netmap.NodeKey,
|
||||
auth_key: ipnDetails.PreAuthKey,
|
||||
},
|
||||
{ method: 'POST' },
|
||||
);
|
||||
}
|
||||
},
|
||||
NotifyBrowseToURL: (url) => {
|
||||
console.log('Browse to URL:', url);
|
||||
},
|
||||
NotifyPanicRecover: (message) => {
|
||||
console.error('Panic recover:', message);
|
||||
},
|
||||
});
|
||||
|
||||
handle.Start();
|
||||
},
|
||||
);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (!sshDetails.username) {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
import { useEffect } from 'react';
|
||||
import { GrApple } from 'react-icons/gr';
|
||||
import { ImFinder } from 'react-icons/im';
|
||||
import { MdAndroid } from 'react-icons/md';
|
||||
import { PiTerminalFill, PiWindowsLogoFill } from 'react-icons/pi';
|
||||
import { LoaderFunctionArgs, NavLink, useLoaderData } from 'react-router';
|
||||
import Button from '~/components/Button';
|
||||
import Card from '~/components/Card';
|
||||
@@ -132,7 +129,7 @@ export default function Page() {
|
||||
key="linux"
|
||||
title={
|
||||
<div className="flex items-center gap-1">
|
||||
<PiTerminalFill className="ml-1 w-4" />
|
||||
<Icon className="ml-1 w-4" icon="ion:terminal" />
|
||||
<span>Linux</span>
|
||||
</div>
|
||||
}
|
||||
@@ -163,7 +160,7 @@ export default function Page() {
|
||||
key="windows"
|
||||
title={
|
||||
<div className="flex items-center gap-1">
|
||||
<PiWindowsLogoFill className="ml-1 w-4" />
|
||||
<Icon className="ml-1 w-4" icon="mdi:microsoft" />
|
||||
<span>Windows</span>
|
||||
</div>
|
||||
}
|
||||
@@ -186,7 +183,10 @@ export default function Page() {
|
||||
key="macos"
|
||||
title={
|
||||
<div className="flex items-center gap-1">
|
||||
<ImFinder className="ml-1 w-4" />
|
||||
<Icon
|
||||
className="ml-1 w-4"
|
||||
icon="streamline-logos:mac-finder-logo-solid"
|
||||
/>
|
||||
<span>macOS</span>
|
||||
</div>
|
||||
}
|
||||
@@ -218,7 +218,7 @@ export default function Page() {
|
||||
key="ios"
|
||||
title={
|
||||
<div className="flex items-center gap-1">
|
||||
<GrApple className="ml-1 w-4" />
|
||||
<Icon className="ml-1 w-4" icon="grommet-icons:apple" />
|
||||
<span>iOS</span>
|
||||
</div>
|
||||
}
|
||||
@@ -241,7 +241,7 @@ export default function Page() {
|
||||
key="android"
|
||||
title={
|
||||
<div className="flex items-center gap-1">
|
||||
<MdAndroid className="ml-1 w-4" />
|
||||
<Icon className="ml-1 w-4" icon="material-symbols:android" />
|
||||
<span>Android</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
+28
-28
@@ -16,20 +16,28 @@
|
||||
"docs:preview": "vitepress preview docs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@libsql/client": "0.15.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.2.0",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/modifiers": "^7.0.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@faker-js/faker": "9.9.0",
|
||||
"@fontsource-variable/inter": "^5.2.6",
|
||||
"@fontsource-variable/inter": "^5.2.8",
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@kubernetes/client-node": "^1.3.0",
|
||||
"@libsql/client": "0.15.12",
|
||||
"@react-aria/toast": "3.0.6",
|
||||
"@react-aria/toast": "3.0.8",
|
||||
"@react-router/dev": "^7.8.1",
|
||||
"@react-router/node": "^7.8.1",
|
||||
"@react-stately/toast": "3.1.2",
|
||||
"@shopify/lang-jsonc": "^1.0.1",
|
||||
"@types/react": "^19.1.10",
|
||||
"@types/react-dom": "^19.1.7",
|
||||
"@tailwindcss/vite": "^4.1.12",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "^19.2.2",
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"@typescript/native-preview": "7.0.0-dev.20250821.1",
|
||||
"@uiw/codemirror-theme-github": "4.25.1",
|
||||
"@uiw/codemirror-theme-xcode": "4.25.1",
|
||||
"@uiw/react-codemirror": "4.25.1",
|
||||
@@ -41,48 +49,40 @@
|
||||
"arktype": "^2.1.20",
|
||||
"clsx": "^2.1.1",
|
||||
"dotenv": "17.2.1",
|
||||
"drizzle-kit": "^0.31.4",
|
||||
"drizzle-orm": "0.44.4",
|
||||
"isbot": "5.1.30",
|
||||
"jose": "6.1.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lefthook": "^1.12.3",
|
||||
"lucide-react": "^0.540.0",
|
||||
"mime": "^4.0.7",
|
||||
"openid-client": "6.7.0",
|
||||
"react": "19.1.1",
|
||||
"react-aria": "3.42.0",
|
||||
"postcss": "^8.5.6",
|
||||
"react": "19.2.0",
|
||||
"react-aria": "3.44.0",
|
||||
"react-codemirror-merge": "4.25.1",
|
||||
"react-dom": "19.1.1",
|
||||
"react-dom": "19.2.0",
|
||||
"react-error-boundary": "^6.0.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router": "^7.8.1",
|
||||
"react-router-dom": "^7.8.1",
|
||||
"react-router-hono-server": "2.21.0",
|
||||
"react-stately": "3.40.0",
|
||||
"react-scan": "^0.4.3",
|
||||
"react-stately": "3.42.0",
|
||||
"remix-utils": "^8.8.0",
|
||||
"tailwind-merge": "3.3.1",
|
||||
"ulidx": "2.4.1",
|
||||
"undici": "7.14.0",
|
||||
"usehooks-ts": "^3.1.1",
|
||||
"yaml": "2.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.2.0",
|
||||
"@react-router/dev": "^7.8.1",
|
||||
"@tailwindcss/vite": "^4.1.12",
|
||||
"@types/node": "^24.3.0",
|
||||
"@typescript/native-preview": "7.0.0-dev.20250821.1",
|
||||
"drizzle-kit": "^0.31.4",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lefthook": "^1.12.3",
|
||||
"postcss": "^8.5.6",
|
||||
"react-router-dom": "^7.8.1",
|
||||
"react-scan": "^0.4.3",
|
||||
"tailwindcss": "^4.1.12",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"tailwindcss-react-aria-components": "^2.0.0",
|
||||
"typescript": "^5.9.2",
|
||||
"ulidx": "2.4.1",
|
||||
"undici": "7.14.0",
|
||||
"usehooks-ts": "^3.1.1",
|
||||
"vite": "npm:rolldown-vite@7.1.4",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitepress": "next",
|
||||
"vitest": "^3.1.3"
|
||||
"vitest": "^3.1.3",
|
||||
"yaml": "2.8.1"
|
||||
},
|
||||
"packageManager": "pnpm@10.4.0",
|
||||
"engines": {
|
||||
|
||||
Generated
+1158
-1310
File diff suppressed because it is too large
Load Diff
+14
-1
@@ -37,10 +37,23 @@ export default defineConfig(({ command, isSsrBuild }) => ({
|
||||
},
|
||||
build: {
|
||||
target: 'esnext',
|
||||
sourcemap: true,
|
||||
rolldownOptions:
|
||||
command === 'build'
|
||||
? {
|
||||
// Exclude libsql from the server side since it's a native module
|
||||
// Exclude WASM from the client since it fetches from the server
|
||||
external: isSsrBuild ? [/^@libsql\//] : [/\.wasm(\?url)?$/],
|
||||
output: {
|
||||
manualChunks: undefined,
|
||||
inlineDynamicImports: isSsrBuild,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
ssr: {
|
||||
target: 'node',
|
||||
noExternal: isSsrBuild ? ['@libsql/client'] : undefined,
|
||||
noExternal: command === 'build' ? true : undefined,
|
||||
},
|
||||
optimizeDeps: {
|
||||
include: ['@libsql/client'],
|
||||
|
||||
Reference in New Issue
Block a user