Rename project to JAMS (Just A simple intelligent Media Server), replace lms- prefix with jams- throughout

This commit is contained in:
2026-05-15 00:10:07 +08:00
parent 31fc98f57f
commit d1adf4e5dc
4 changed files with 112 additions and 105 deletions
+44 -42
View File
@@ -1,4 +1,6 @@
# LLM Media Server — Architecture Design
# JAMS — Architecture Design
> **JAMS**: Just A simple intelligent Media Server
> Patterns derived from Jellyfin's architecture, implemented in Rust.
@@ -7,17 +9,17 @@
## 1. Cargo Workspace Layout
```
lms/ ← workspace root
jams/ ← workspace root
├── Cargo.toml ← workspace members
├── crates/
│ ├── lms-server/ ← binary entry, Axum router, DI wiring
│ ├── lms-core/ ← shared traits, domain types, error types
│ ├── lms-library/ ← LibraryManager, FileWatcher, MediaResolver
│ ├── lms-metadata/ ← MetadataRouter + provider implementations
│ ├── lms-llm/ ← LlmRouter + LLM provider implementations
│ ├── lms-media/ ← ffmpeg wrapper, MediaProbe, thumbnail extractor
│ ├── lms-stream/ ← StreamBuilder, direct play, HLS handler
│ └── lms-db/ ← SQLite/sqlx, migrations, repositories
│ ├── jams-server/ ← binary entry, Axum router, DI wiring
│ ├── jams-core/ ← shared traits, domain types, error types
│ ├── jams-library/ ← LibraryManager, FileWatcher, MediaResolver
│ ├── jams-metadata/ ← MetadataRouter + provider implementations
│ ├── jams-llm/ ← LlmRouter + LLM provider implementations
│ ├── jams-media/ ← ffmpeg wrapper, MediaProbe, thumbnail extractor
│ ├── jams-stream/ ← StreamBuilder, direct play, HLS handler
│ └── jams-db/ ← SQLite/sqlx, migrations, repositories
├── docs/
└── docker/
├── Dockerfile
@@ -27,27 +29,27 @@ lms/ ← workspace root
**Dependency direction** (one-way, no cycles):
```
lms-server
├── lms-library → lms-core, lms-db
├── lms-metadata → lms-core, lms-llm
├── lms-llm → lms-core
├── lms-media → lms-core
├── lms-stream → lms-core, lms-media, lms-db
└── lms-db → lms-core
jams-server
├── jams-library → jams-core, jams-db
├── jams-metadata → jams-core, jams-llm
├── jams-llm → jams-core
├── jams-media → jams-core
├── jams-stream → jams-core, jams-media, jams-db
└── jams-db → jams-core
```
`lms-core` has zero internal dependencies. All traits are defined here.
`jams-core` has zero internal dependencies. All traits are defined here.
---
## 2. Core Traits (lms-core)
## 2. Core Traits (jams-core)
Mirroring Jellyfin's `IMetadataProvider` hierarchy using Rust trait objects.
### 2.1 Metadata Provider
```rust
// crates/lms-core/src/providers/metadata.rs
// crates/jams-core/src/providers/metadata.rs
#[async_trait]
pub trait MetadataProvider: Send + Sync {
@@ -88,7 +90,7 @@ pub struct MetadataResult {
### 2.2 LLM Provider
```rust
// crates/lms-core/src/providers/llm.rs
// crates/jams-core/src/providers/llm.rs
#[async_trait]
pub trait LlmProvider: Send + Sync {
@@ -109,7 +111,7 @@ pub struct LlmOptions {
Inspired by Jellyfin's `BaseItem`, but using a Rust enum hierarchy instead of class inheritance.
```rust
// crates/lms-core/src/domain/item.rs
// crates/jams-core/src/domain/item.rs
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MediaItem {
@@ -214,7 +216,7 @@ mpsc::channel<IngestEvent>
## 4. MediaResolver — Filename Parsing (ref: Emby.Naming)
```rust
// crates/lms-library/src/resolver.rs
// crates/jams-library/src/resolver.rs
pub struct MediaResolver {
episode_patterns: Vec<Regex>, // compiled once at startup
@@ -249,7 +251,7 @@ const EPISODE_PATTERNS: &[&str] = &[
## 5. MetadataRouter — Priority Routing (ref: Jellyfin ProviderManager)
```rust
// crates/lms-metadata/src/router.rs
// crates/jams-metadata/src/router.rs
pub struct MetadataRouter {
providers: Vec<Box<dyn MetadataProvider>>, // sorted by priority()
@@ -289,7 +291,7 @@ impl MetadataRouter {
## 6. LlmRouter — Multi-Provider with Fallback
```rust
// crates/lms-llm/src/router.rs
// crates/jams-llm/src/router.rs
pub struct LlmRouter {
primary: Box<dyn LlmProvider>,
@@ -316,7 +318,7 @@ impl LlmRouter {
}
// Provider implementations:
// crates/lms-llm/src/providers/
// crates/jams-llm/src/providers/
// ollama.rs → GET http://localhost:11434/api/generate
// claude.rs → POST https://api.anthropic.com/v1/messages
// openai.rs → POST https://api.openai.com/v1/chat/completions
@@ -327,7 +329,7 @@ impl LlmRouter {
## 7. StreamBuilder — Decision Tree (ref: Jellyfin StreamBuilder.cs)
```rust
// crates/lms-stream/src/builder.rs
// crates/jams-stream/src/builder.rs
pub enum StreamPlan {
DirectPlay { path: PathBuf },
@@ -367,7 +369,7 @@ impl StreamBuilder {
---
## 8. Database Schema (lms-db)
## 8. Database Schema (jams-db)
```sql
CREATE TABLE media_items (
@@ -513,11 +515,11 @@ base_url = "https://api.openai.com/v1"
model = "gpt-4o"
[streaming]
transcode_dir = "/tmp/lms-transcode"
transcode_dir = "/tmp/jams-transcode"
max_concurrent_jobs = 2
[db]
path = "/data/lms.db"
path = "/data/jams.db"
```
---
@@ -534,10 +536,10 @@ services:
volumes:
- ./config:/config # config + SQLite DB
- /your/media:/media:ro # media library (read-only)
- /tmp/lms-transcode:/transcode
- /tmp/jams-transcode:/transcode
environment:
- LMS_DB_PATH=/config/lms.db
- LMS_CONFIG=/config/lms.toml
- JAMS_DB_PATH=/config/jams.db
- JAMS_CONFIG=/config/jams.toml
restart: unless-stopped
ollama:
@@ -555,13 +557,13 @@ volumes:
FROM rust:1.82-slim AS builder
WORKDIR /app
COPY . .
RUN cargo build --release --bin lms-server
RUN cargo build --release --bin jams-server
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ffmpeg ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/lms-server /usr/local/bin/lms-server
COPY --from=builder /app/target/release/jams-server /usr/local/bin/jams-server
EXPOSE 3000
ENTRYPOINT ["lms-server"]
ENTRYPOINT ["jams-server"]
```
---
@@ -569,14 +571,14 @@ ENTRYPOINT ["lms-server"]
## 12. Key Crate Dependencies
```toml
# lms-server
# jams-server
axum = "0.7"
tokio = { version = "1", features = ["full"] }
tower-http = { version = "0.5", features = ["cors", "trace"] }
tracing = "0.1"
tracing-subscriber = "0.3"
# lms-core
# jams-core
serde = { version = "1", features = ["derive"] }
serde_json = "1"
uuid = { version = "1", features = ["v4"] }
@@ -584,17 +586,17 @@ chrono = { version = "0.4", features = ["serde"] }
async-trait = "0.1"
thiserror = "1"
# lms-library
# jams-library
notify = "6"
regex = "1"
# lms-db
# jams-db
sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio", "migrate", "uuid", "chrono"] }
# lms-llm / lms-metadata
# jams-llm / jams-metadata
reqwest = { version = "0.12", features = ["json"] }
# lms-media
# jams-media
tokio-process = "1"
```