Deploy
This commit is contained in:
8
.env_dist
Normal file
8
.env_dist
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Script saving configuration
|
||||||
|
ENABLE_SAVE=true
|
||||||
|
SAVE_SECRET=save
|
||||||
|
SAVE_DIRECTORY=./data/scripts
|
||||||
|
MAX_FILENAME_LENGTH=32
|
||||||
|
|
||||||
|
# Next.js environment
|
||||||
|
NODE_ENV=production
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ target
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
webui/src/wasm
|
webui/src/wasm
|
||||||
webui/data
|
webui/data
|
||||||
|
.env
|
||||||
|
|||||||
30
Dockerfile
Normal file
30
Dockerfile
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
FROM rust:1.91 AS rust-builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
RUN cargo install wasm-pack
|
||||||
|
|
||||||
|
COPY rust/ ./rust/
|
||||||
|
WORKDIR /app/rust/rhai-codemirror
|
||||||
|
RUN wasm-pack build --target web --out-dir "../../webui/src/wasm/rhai-codemirror"
|
||||||
|
|
||||||
|
WORKDIR /app/rust/runner
|
||||||
|
RUN wasm-pack build --target web --out-dir "../../webui/src/wasm/runner"
|
||||||
|
|
||||||
|
FROM node:24-alpine AS app
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN npm install -g bun
|
||||||
|
COPY webui/package.json webui/bun.lock* ./webui/
|
||||||
|
|
||||||
|
WORKDIR /app/webui
|
||||||
|
RUN bun install --frozen-lockfile
|
||||||
|
COPY webui/ ./
|
||||||
|
COPY --from=rust-builder /app/webui/src/wasm/ ./src/wasm/
|
||||||
|
|
||||||
|
RUN bun run build
|
||||||
|
|
||||||
|
RUN mkdir -p ../data/scripts
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD ["bun", "start"]
|
||||||
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
webui:
|
||||||
|
image: minimax
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
- ./data:/app/data
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: unless-stopped
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
mod ansi;
|
mod ansi;
|
||||||
mod gamestate;
|
mod minmaxgame;
|
||||||
mod gamestatehuman;
|
mod minmaxgamehuman;
|
||||||
mod terminput;
|
mod terminput;
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use wasm_bindgen::prelude::*;
|
|||||||
use crate::{ansi, terminput::TermInput};
|
use crate::{ansi, terminput::TermInput};
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct GameStateHuman {
|
pub struct MinMaxGameHuman {
|
||||||
/// Red player
|
/// Red player
|
||||||
human: TermInput,
|
human: TermInput,
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ pub struct GameStateHuman {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl GameStateHuman {
|
impl MinMaxGameHuman {
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
max_script: &str,
|
max_script: &str,
|
||||||
@@ -34,7 +34,7 @@ impl GameStateHuman {
|
|||||||
max_debug_callback: js_sys::Function,
|
max_debug_callback: js_sys::Function,
|
||||||
|
|
||||||
game_state_callback: js_sys::Function,
|
game_state_callback: js_sys::Function,
|
||||||
) -> Result<GameStateHuman, String> {
|
) -> Result<MinMaxGameHuman, String> {
|
||||||
Self::new_native(
|
Self::new_native(
|
||||||
max_script,
|
max_script,
|
||||||
move |s| {
|
move |s| {
|
||||||
@@ -24,7 +24,7 @@ export async function GET(request: NextRequest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveDir = join(process.cwd(), SAVE_CONFIG.SAVE_DIRECTORY);
|
const saveDir = SAVE_CONFIG.SAVE_DIRECTORY;
|
||||||
const filename = `${name}.rhai`;
|
const filename = `${name}.rhai`;
|
||||||
const filepath = join(saveDir, filename);
|
const filepath = join(saveDir, filename);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { SAVE_CONFIG } from "@/lib/saveConfig";
|
|||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
try {
|
try {
|
||||||
const saveDir = join(process.cwd(), SAVE_CONFIG.SAVE_DIRECTORY);
|
const saveDir = SAVE_CONFIG.SAVE_DIRECTORY;
|
||||||
|
|
||||||
// If save directory doesn't exist, return empty array
|
// If save directory doesn't exist, return empty array
|
||||||
if (!existsSync(saveDir)) {
|
if (!existsSync(saveDir)) {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export async function POST(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure save directory exists
|
// Ensure save directory exists
|
||||||
const saveDir = join(process.cwd(), SAVE_CONFIG.SAVE_DIRECTORY);
|
const saveDir = SAVE_CONFIG.SAVE_DIRECTORY;
|
||||||
if (!existsSync(saveDir)) {
|
if (!existsSync(saveDir)) {
|
||||||
await mkdir(saveDir, { recursive: true });
|
await mkdir(saveDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
export const SAVE_CONFIG = {
|
export const SAVE_CONFIG = {
|
||||||
ENABLE_SAVE: true,
|
ENABLE_SAVE: process.env.ENABLE_SAVE === 'true' || true,
|
||||||
SAVE_SECRET: "save",
|
SAVE_SECRET: process.env.SAVE_SECRET || "save",
|
||||||
|
|
||||||
SAVE_DIRECTORY: "./data/scripts",
|
SAVE_DIRECTORY: process.env.SAVE_DIRECTORY || "./data/scripts",
|
||||||
MAX_FILENAME_LENGTH: 32,
|
MAX_FILENAME_LENGTH: parseInt(process.env.MAX_FILENAME_LENGTH || "32"),
|
||||||
FILENAME_REGEX: /^[a-zA-Z0-9_\s-]+$/,
|
FILENAME_REGEX: /^[a-zA-Z0-9_\s-]+$/,
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import init, { GameState, GameStateHuman } from "../wasm/runner";
|
import init, { MinMaxGameHuman } from "../wasm/runner";
|
||||||
|
|
||||||
let wasmReady = false;
|
let wasmReady = false;
|
||||||
let wasmInitPromise: Promise<void> | null = null;
|
let wasmInitPromise: Promise<void> | null = null;
|
||||||
let currentGame: GameStateHuman | null = null;
|
let currentGame: MinMaxGameHuman | null = null;
|
||||||
|
|
||||||
async function initWasm(): Promise<void> {
|
async function initWasm(): Promise<void> {
|
||||||
if (wasmReady) return;
|
if (wasmReady) return;
|
||||||
@@ -53,7 +53,7 @@ self.onmessage = async (event) => {
|
|||||||
self.postMessage({ type: "terminal", line });
|
self.postMessage({ type: "terminal", line });
|
||||||
};
|
};
|
||||||
|
|
||||||
currentGame = new GameStateHuman(
|
currentGame = new MinMaxGameHuman(
|
||||||
event_data.script,
|
event_data.script,
|
||||||
appendOutput,
|
appendOutput,
|
||||||
appendOutput,
|
appendOutput,
|
||||||
|
|||||||
Reference in New Issue
Block a user