commit a4b7c82b1a391af0cb1826145fd61a1c037dea4b Author: default Date: Sat Jan 24 02:32:25 2026 +0000 Inital Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b35480 --- /dev/null +++ b/.gitignore @@ -0,0 +1,72 @@ +# General +.DS_Store +.AppleDouble +.LSOverride +Thumbs.db +desktop.ini + +# VS Code +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +.history/ + +# Node.js / Javascript +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +bun.lockb +.npm/ + +# SvelteKit +.svelte-kit/ +build/ +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# Python Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Tauri +src-tauri/target/ +src-tauri/gen/ + +bun.lock +.vscode/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..9a5aeee --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,24 @@ +# Use a lightweight Python image +FROM python:3.9-slim + +# Set working directory inside the container +WORKDIR /app + +# Copy requirements first (for better caching) +COPY requirements.txt . + +# Install dependencies +# 'gunicorn' must be in your requirements.txt or installed here +RUN pip install --no-cache-dir -r requirements.txt +RUN pip install gunicorn + +# Copy the rest of the application +COPY . . + +# Expose the internal port (Gunicorn default is 8000, or we choose one) +EXPOSE 5000 + +# Command to run production server +# -w 4: 4 worker processes +# -b 0.0.0.0:5000: Bind to all interfaces inside container on port 5000 +CMD ["gunicorn", "--workers", "4", "--bind", "0.0.0.0:5000", "app:app"] diff --git a/backend/app.py b/backend/app.py new file mode 100644 index 0000000..fc7fa1a --- /dev/null +++ b/backend/app.py @@ -0,0 +1,9 @@ +from dotenv import load_dotenv +load_dotenv() + +from src import create_app + +app = create_app() + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..6f0c0e3 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,12 @@ +flask +google-genai +gunicorn +pymongo +ultralytics +opencv-python-headless +transformers +torch +pandas +pypdf +python-dotenv +flask-cors diff --git a/backend/src/__init__.py b/backend/src/__init__.py new file mode 100644 index 0000000..fd896c1 --- /dev/null +++ b/backend/src/__init__.py @@ -0,0 +1,14 @@ +from flask import Flask +from flask_cors import CORS +from .routes.main import main_bp +from .routes.rag import rag_bp + +def create_app(): + app = Flask(__name__) + CORS(app) # Enable CORS for all routes + + # Register Blueprints + app.register_blueprint(main_bp) + app.register_blueprint(rag_bp, url_prefix='/api/rag') + + return app diff --git a/backend/src/cv/__init__.py b/backend/src/cv/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/gemini/__init__.py b/backend/src/gemini/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/gemini/client.py b/backend/src/gemini/client.py new file mode 100644 index 0000000..b54aaff --- /dev/null +++ b/backend/src/gemini/client.py @@ -0,0 +1,21 @@ +from google import genai +import os + +def generate_content(prompt, model_name="gemini-2.0-flash-exp"): + """ + Generates content using the Google GenAI SDK. + Defaults to gemini-2.0-flash-exp as per request (or similar). + """ + api_key = os.environ.get("GOOGLE_API_KEY") + if not api_key: + return "Error: GOOGLE_API_KEY not found." + + try: + client = genai.Client(api_key=api_key) + response = client.models.generate_content( + model=model_name, + contents=prompt, + ) + return response.text + except Exception as e: + return f"Error interacting with Gemini API: {str(e)}" diff --git a/backend/src/mongo/__init__.py b/backend/src/mongo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/rag/embeddings.py b/backend/src/rag/embeddings.py new file mode 100644 index 0000000..cbb9d2d --- /dev/null +++ b/backend/src/rag/embeddings.py @@ -0,0 +1,33 @@ +from google import genai +import os + +def get_embedding(text, model="gemini-embedding-001"): + """ + Generates an embedding for the given text using the Gemini API. + """ + api_key = os.environ.get("GOOGLE_API_KEY") + if not api_key: + raise ValueError("GOOGLE_API_KEY environment variable not set") + + client = genai.Client(api_key=api_key) + result = client.models.embed_content( + model=model, + contents=text + ) + return result.embeddings[0].values + +def get_embeddings_batch(texts, model="gemini-embedding-001"): + """ + Generates embeddings for a list of texts. + """ + api_key = os.environ.get("GOOGLE_API_KEY") + if not api_key: + raise ValueError("GOOGLE_API_KEY environment variable not set") + + client = genai.Client(api_key=api_key) + result = client.models.embed_content( + model=model, + contents=texts + ) + # The SDK returns a list of embedding objects + return [emb.values for emb in result.embeddings] diff --git a/backend/src/rag/ingest.py b/backend/src/rag/ingest.py new file mode 100644 index 0000000..a1a6209 --- /dev/null +++ b/backend/src/rag/ingest.py @@ -0,0 +1,37 @@ +import pandas as pd +from pypdf import PdfReader +import io +import os + +def load_csv(file_path): + """ + Loads a CSV file and returns a list of strings (one per row). + This is a simplistic implementation - in production you might want specific columns. + """ + df = pd.read_csv(file_path) + # Convert each row to a string representation + return df.apply(lambda x: ' | '.join(x.astype(str)), axis=1).tolist() + +def load_pdf(file_path): + """ + Loads a PDF file and returns a list of strings (one per page). + """ + reader = PdfReader(file_path) + text_chunks = [] + for page in reader.pages: + text = page.extract_text() + if text: + text_chunks.append(text) + return text_chunks + +def process_file(file_path): + """ + Determines file type and returns text chunks. + """ + ext = os.path.splitext(file_path)[1].lower() + if ext == '.csv': + return load_csv(file_path) + elif ext == '.pdf': + return load_pdf(file_path) + else: + raise ValueError(f"Unsupported file type: {ext}") diff --git a/backend/src/rag/store.py b/backend/src/rag/store.py new file mode 100644 index 0000000..3a798a1 --- /dev/null +++ b/backend/src/rag/store.py @@ -0,0 +1,67 @@ +import os +from pymongo import MongoClient +from .embeddings import get_embeddings_batch + +def get_mongo_client(): + uri = os.environ.get("MONGO_URI") + if not uri: + raise ValueError("MONGO_URI environment variable not set") + return MongoClient(uri) + +def ingest_documents(text_chunks, collection_name="rag_documents"): + """ + Generates embeddings for text chunks and stores them in MongoDB. + """ + client = get_mongo_client() + db = client.get_database("vectors_db") # Default DB name + collection = db[collection_name] + + # Generate embeddings in batches (handling API limits might be needed for large sets) + embeddings = get_embeddings_batch(text_chunks) + + documents = [] + for text, embedding in zip(text_chunks, embeddings): + documents.append({ + "text": text, + "embedding": embedding + }) + + if documents: + collection.insert_many(documents) + return len(documents) + return 0 + +def vector_search(query_text, collection_name="rag_documents", num_results=5): + """ + Performs a vector search in MongoDB. + """ + # 1. Get embedding for the query + from .embeddings import get_embedding + query_embedding = get_embedding(query_text) + + client = get_mongo_client() + db = client.get_database("vectors_db") + collection = db[collection_name] + + # Note: You must have a vector search index defined in MongoDB Atlas for this to work. + pipeline = [ + { + "$vectorSearch": { + "index": "vector_index", + "path": "embedding", + "queryVector": query_embedding, + "numCandidates": num_results * 10, + "limit": num_results + } + }, + { + "$project": { + "_id": 0, + "text": 1, + "score": { "$meta": "vectorSearchScore" } + } + } + ] + + results = list(collection.aggregate(pipeline)) + return results diff --git a/backend/src/routes/__init__.py b/backend/src/routes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/routes/main.py b/backend/src/routes/main.py new file mode 100644 index 0000000..d615f68 --- /dev/null +++ b/backend/src/routes/main.py @@ -0,0 +1,7 @@ +from flask import Blueprint + +main_bp = Blueprint('main', __name__) + +@main_bp.route('/') +def index(): + return "Hello from the organized Flask App!" diff --git a/backend/src/routes/rag.py b/backend/src/routes/rag.py new file mode 100644 index 0000000..dae504c --- /dev/null +++ b/backend/src/routes/rag.py @@ -0,0 +1,24 @@ +from flask import Blueprint, request, jsonify +from ..rag.store import vector_search, ingest_documents + +rag_bp = Blueprint('rag', __name__) + +@rag_bp.route('/ingest', methods=['POST']) +def ingest(): + data = request.json + text_chunks = data.get('chunks', []) + if not text_chunks: + return jsonify({"error": "No chunks provided"}), 400 + + count = ingest_documents(text_chunks) + return jsonify({"message": f"Ingested {count} documents"}), 201 + +@rag_bp.route('/search', methods=['POST']) +def search(): + data = request.json + query = data.get('query') + if not query: + return jsonify({"error": "No query provided"}), 400 + + results = vector_search(query) + return jsonify({"results": results}), 200 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4b371c7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + # The Flask Backend + api: + build: ./backend # Path to your Dockerfile + container_name: flask_api + restart: always + ports: + - "5000:5000" # Maps VM Port 5000 -> Container Port 5000 + environment: + - SECRET_KEY=your_secret_key_here + # Add database URLs here later + + # (Optional) Add a database or cache here easily later + # redis: + # image: redis:alpine diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..6635cf5 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..858d179 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,7 @@ +# Tauri + SvelteKit + TypeScript + +This template should help get you started developing with Tauri, SvelteKit and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer). diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..1467b88 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,29 @@ +{ + "name": "ethix", + "version": "0.1.0", + "description": "", + "type": "module", + "scripts": { + "dev": "vite dev --host", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "tauri": "tauri" + }, + "license": "MIT", + "dependencies": { + "@tauri-apps/api": "^2.9.1", + "@tauri-apps/plugin-opener": "^2.5.3" + }, + "devDependencies": { + "@sveltejs/adapter-static": "^3.0.10", + "@sveltejs/kit": "^2.50.1", + "@sveltejs/vite-plugin-svelte": "^5.1.1", + "svelte": "^5.48.0", + "svelte-check": "^4.3.5", + "typescript": "~5.6.3", + "vite": "^6.4.1", + "@tauri-apps/cli": "^2.9.6" + } +} diff --git a/frontend/src-tauri/.gitignore b/frontend/src-tauri/.gitignore new file mode 100644 index 0000000..b21bd68 --- /dev/null +++ b/frontend/src-tauri/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Generated by Tauri +# will have schema files for capabilities auto-completion +/gen/schemas diff --git a/frontend/src-tauri/Cargo.toml b/frontend/src-tauri/Cargo.toml new file mode 100644 index 0000000..1a49f7c --- /dev/null +++ b/frontend/src-tauri/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "ethix" +version = "0.1.0" +description = "A Tauri App" +authors = ["you"] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +# The `_lib` suffix may seem redundant but it is necessary +# to make the lib name unique and wouldn't conflict with the bin name. +# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519 +name = "ethix_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2", features = [] } + +[dependencies] +tauri = { version = "2", features = [] } +tauri-plugin-opener = "2" +serde = { version = "1", features = ["derive"] } +serde_json = "1" + diff --git a/frontend/src-tauri/build.rs b/frontend/src-tauri/build.rs new file mode 100644 index 0000000..d860e1e --- /dev/null +++ b/frontend/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/frontend/src-tauri/capabilities/default.json b/frontend/src-tauri/capabilities/default.json new file mode 100644 index 0000000..4cdbf49 --- /dev/null +++ b/frontend/src-tauri/capabilities/default.json @@ -0,0 +1,10 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": [ + "core:default", + "opener:default" + ] +} diff --git a/frontend/src-tauri/icons/128x128.png b/frontend/src-tauri/icons/128x128.png new file mode 100644 index 0000000..6be5e50 Binary files /dev/null and b/frontend/src-tauri/icons/128x128.png differ diff --git a/frontend/src-tauri/icons/128x128@2x.png b/frontend/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000..e81bece Binary files /dev/null and b/frontend/src-tauri/icons/128x128@2x.png differ diff --git a/frontend/src-tauri/icons/32x32.png b/frontend/src-tauri/icons/32x32.png new file mode 100644 index 0000000..a437dd5 Binary files /dev/null and b/frontend/src-tauri/icons/32x32.png differ diff --git a/frontend/src-tauri/icons/Square107x107Logo.png b/frontend/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000..0ca4f27 Binary files /dev/null and b/frontend/src-tauri/icons/Square107x107Logo.png differ diff --git a/frontend/src-tauri/icons/Square142x142Logo.png b/frontend/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000..b81f820 Binary files /dev/null and b/frontend/src-tauri/icons/Square142x142Logo.png differ diff --git a/frontend/src-tauri/icons/Square150x150Logo.png b/frontend/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000..624c7bf Binary files /dev/null and b/frontend/src-tauri/icons/Square150x150Logo.png differ diff --git a/frontend/src-tauri/icons/Square284x284Logo.png b/frontend/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000..c021d2b Binary files /dev/null and b/frontend/src-tauri/icons/Square284x284Logo.png differ diff --git a/frontend/src-tauri/icons/Square30x30Logo.png b/frontend/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000..6219700 Binary files /dev/null and b/frontend/src-tauri/icons/Square30x30Logo.png differ diff --git a/frontend/src-tauri/icons/Square310x310Logo.png b/frontend/src-tauri/icons/Square310x310Logo.png new file mode 100644 index 0000000..f9bc048 Binary files /dev/null and b/frontend/src-tauri/icons/Square310x310Logo.png differ diff --git a/frontend/src-tauri/icons/Square44x44Logo.png b/frontend/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000..d5fbfb2 Binary files /dev/null and b/frontend/src-tauri/icons/Square44x44Logo.png differ diff --git a/frontend/src-tauri/icons/Square71x71Logo.png b/frontend/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000..63440d7 Binary files /dev/null and b/frontend/src-tauri/icons/Square71x71Logo.png differ diff --git a/frontend/src-tauri/icons/Square89x89Logo.png b/frontend/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000..f3f705a Binary files /dev/null and b/frontend/src-tauri/icons/Square89x89Logo.png differ diff --git a/frontend/src-tauri/icons/StoreLogo.png b/frontend/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000..4556388 Binary files /dev/null and b/frontend/src-tauri/icons/StoreLogo.png differ diff --git a/frontend/src-tauri/icons/icon.icns b/frontend/src-tauri/icons/icon.icns new file mode 100644 index 0000000..12a5bce Binary files /dev/null and b/frontend/src-tauri/icons/icon.icns differ diff --git a/frontend/src-tauri/icons/icon.ico b/frontend/src-tauri/icons/icon.ico new file mode 100644 index 0000000..b3636e4 Binary files /dev/null and b/frontend/src-tauri/icons/icon.ico differ diff --git a/frontend/src-tauri/icons/icon.png b/frontend/src-tauri/icons/icon.png new file mode 100644 index 0000000..e1cd261 Binary files /dev/null and b/frontend/src-tauri/icons/icon.png differ diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs new file mode 100644 index 0000000..4a277ef --- /dev/null +++ b/frontend/src-tauri/src/lib.rs @@ -0,0 +1,14 @@ +// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ +#[tauri::command] +fn greet(name: &str) -> String { + format!("Hello, {}! You've been greeted from Rust!", name) +} + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_opener::init()) + .invoke_handler(tauri::generate_handler![greet]) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} diff --git a/frontend/src-tauri/src/main.rs b/frontend/src-tauri/src/main.rs new file mode 100644 index 0000000..034cf91 --- /dev/null +++ b/frontend/src-tauri/src/main.rs @@ -0,0 +1,6 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +fn main() { + ethix_lib::run() +} diff --git a/frontend/src-tauri/tauri.conf.json b/frontend/src-tauri/tauri.conf.json new file mode 100644 index 0000000..ea28b66 --- /dev/null +++ b/frontend/src-tauri/tauri.conf.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "productName": "ethix", + "version": "0.1.0", + "identifier": "tech.ethix.app", + "build": { + "beforeDevCommand": "bun run dev", + "devUrl": "http://localhost:1420", + "beforeBuildCommand": "bun run build", + "frontendDist": "../build" + }, + "app": { + "windows": [ + { + "title": "ethix", + "width": 800, + "height": 600 + } + ], + "security": { + "csp": null + } + }, + "bundle": { + "active": true, + "targets": "all", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ] + } +} diff --git a/frontend/src/app.html b/frontend/src/app.html new file mode 100644 index 0000000..92e7e33 --- /dev/null +++ b/frontend/src/app.html @@ -0,0 +1,13 @@ + + + + + + + Tauri + SvelteKit + Typescript App + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte new file mode 100644 index 0000000..b10f5dd --- /dev/null +++ b/frontend/src/routes/+layout.svelte @@ -0,0 +1,78 @@ + + + +{#if isApp} +
+ {@render children()} +
+ +{:else} + +
+ {@render children()} +
+ +{/if} + + diff --git a/frontend/src/routes/+layout.ts b/frontend/src/routes/+layout.ts new file mode 100644 index 0000000..9d24899 --- /dev/null +++ b/frontend/src/routes/+layout.ts @@ -0,0 +1,5 @@ +// Tauri doesn't have a Node.js server to do proper SSR +// so we use adapter-static with a fallback to index.html to put the site in SPA mode +// See: https://svelte.dev/docs/kit/single-page-apps +// See: https://v2.tauri.app/start/frontend/sveltekit/ for more info +export const ssr = false; diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte new file mode 100644 index 0000000..ed3b648 --- /dev/null +++ b/frontend/src/routes/+page.svelte @@ -0,0 +1,232 @@ + + +
+

Welcome to Tauri + Svelte

+ + +
+

Get the App

+

+ Experience the full power of our platform with the native app. +

+ Download for Android +
+
+ + +
+

📱 You are using the Native App!

+
+
+ + +

Click on the Tauri, Vite, and SvelteKit logos to learn more.

+ +
+ + +
+

{greetMsg}

+
+ + diff --git a/frontend/static/favicon.png b/frontend/static/favicon.png new file mode 100644 index 0000000..825b9e6 Binary files /dev/null and b/frontend/static/favicon.png differ diff --git a/frontend/static/svelte.svg b/frontend/static/svelte.svg new file mode 100644 index 0000000..c5e0848 --- /dev/null +++ b/frontend/static/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/static/tauri.svg b/frontend/static/tauri.svg new file mode 100644 index 0000000..31b62c9 --- /dev/null +++ b/frontend/static/tauri.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/static/vite.svg b/frontend/static/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/frontend/static/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js new file mode 100644 index 0000000..a7830ea --- /dev/null +++ b/frontend/svelte.config.js @@ -0,0 +1,18 @@ +// Tauri doesn't have a Node.js server to do proper SSR +// so we use adapter-static with a fallback to index.html to put the site in SPA mode +// See: https://svelte.dev/docs/kit/single-page-apps +// See: https://v2.tauri.app/start/frontend/sveltekit/ for more info +import adapter from "@sveltejs/adapter-static"; +import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + preprocess: vitePreprocess(), + kit: { + adapter: adapter({ + fallback: "index.html", + }), + }, +}; + +export default config; diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..f4d0a0e --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/frontend/vite.config.js b/frontend/vite.config.js new file mode 100644 index 0000000..3ecfa0a --- /dev/null +++ b/frontend/vite.config.js @@ -0,0 +1,32 @@ +import { defineConfig } from "vite"; +import { sveltekit } from "@sveltejs/kit/vite"; + +// @ts-expect-error process is a nodejs global +const host = process.env.TAURI_DEV_HOST; + +// https://vite.dev/config/ +export default defineConfig(async () => ({ + plugins: [sveltekit()], + + // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` + // + // 1. prevent Vite from obscuring rust errors + clearScreen: false, + // 2. tauri expects a fixed port, fail if that port is not available + server: { + port: 1420, + strictPort: true, + host: host || false, + hmr: host + ? { + protocol: "ws", + host, + port: 1421, + } + : undefined, + watch: { + // 3. tell Vite to ignore watching `src-tauri` + ignored: ["**/src-tauri/**"], + }, + }, +}));