267 lines
8.9 KiB
Markdown
267 lines
8.9 KiB
Markdown
# Module Dependency Graph
|
|
|
|
## Visual Hierarchy
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Root Project │
|
|
│ (Amethyst) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
│
|
|
┌────────────────┼────────────────┬────────────┐
|
|
│ │ │ │
|
|
▼ ▼ ▼ ▼
|
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────┐
|
|
│ :amethyst │ │ :desktopApp │ │ :benchmark │ │:ammolite │
|
|
│ (Android) │ │ (JVM) │ │ (Android) │ │ (Support)│
|
|
└─────────────┘ └─────────────┘ └─────────────┘ └──────────┘
|
|
│ │ │
|
|
│ │ │
|
|
└────────────────┼────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ :commons │
|
|
│ (KMP UI) │
|
|
│ │
|
|
│ jvmAndroid │
|
|
│ / \ │
|
|
│ jvm android│
|
|
└─────────────┘
|
|
│
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ :quartz │
|
|
│(KMP Library)│
|
|
│ │
|
|
│ commonMain │
|
|
│ │ │
|
|
│ jvmAndroid │
|
|
│ / | \ │
|
|
│jvm and ios │
|
|
└─────────────┘
|
|
```
|
|
|
|
## Module Details
|
|
|
|
### :quartz (KMP Nostr Library)
|
|
**Type:** Kotlin Multiplatform Library
|
|
**Targets:** JVM, Android, iOS (iosX64, iosArm64, iosSimulatorArm64)
|
|
**Dependencies:**
|
|
- External: secp256k1, jackson, okhttp, kotlinx.coroutines, kotlinx.collections.immutable
|
|
- Source sets: commonMain → jvmAndroid → {androidMain, jvmMain}, iosMain
|
|
|
|
**Role:** Core Nostr protocol implementation, shared across all platforms
|
|
|
|
### :commons (Shared UI Components)
|
|
**Type:** Kotlin Multiplatform Library
|
|
**Targets:** JVM, Android
|
|
**Dependencies:**
|
|
- Module: `:quartz`
|
|
- External: Compose Multiplatform, Material3, kotlinx.collections.immutable
|
|
- Source sets: commonMain → jvmAndroid → {androidMain, jvmMain}
|
|
|
|
**Role:** Shared Compose UI components for Desktop and Android
|
|
|
|
### :desktopApp (Desktop Application)
|
|
**Type:** JVM Application
|
|
**Targets:** JVM (Desktop)
|
|
**Dependencies:**
|
|
- Modules: `:commons`, `:quartz`
|
|
- External: Compose Desktop, kotlinx.coroutines.swing
|
|
|
|
**Role:** Desktop-specific navigation, layouts, and entry point
|
|
|
|
### :amethyst (Android Application)
|
|
**Type:** Android Application
|
|
**Targets:** Android
|
|
**Dependencies:**
|
|
- Modules: `:commons`, `:quartz`, `:ammolite`
|
|
- External: Android SDK, AndroidX, Firebase, Tor
|
|
|
|
**Role:** Android-specific navigation, layouts, and entry point
|
|
|
|
### :benchmark (Android Benchmark)
|
|
**Type:** Android Library
|
|
**Targets:** Android
|
|
**Dependencies:**
|
|
- Modules: `:commons`, `:quartz`
|
|
- External: AndroidX Benchmark
|
|
|
|
**Role:** Performance benchmarking for Android builds
|
|
|
|
### :ammolite (Support Module)
|
|
**Type:** Android Library
|
|
**Targets:** Android
|
|
**Dependencies:** Android-specific utilities
|
|
|
|
**Role:** Android support utilities for amethyst
|
|
|
|
## Dependency Flow Patterns
|
|
|
|
### Desktop Build Chain
|
|
```
|
|
:desktopApp → :commons (jvmMain) → :quartz (jvmMain)
|
|
↓
|
|
jvmAndroid
|
|
↓
|
|
commonMain
|
|
```
|
|
|
|
### Android Build Chain
|
|
```
|
|
:amethyst → :commons (androidMain) → :quartz (androidMain)
|
|
↓ ↓
|
|
:ammolite jvmAndroid
|
|
↓
|
|
commonMain
|
|
```
|
|
|
|
## Source Set Dependencies
|
|
|
|
### :quartz Source Sets
|
|
```
|
|
commonMain (base)
|
|
├─ jvmAndroid (shared JVM code)
|
|
│ ├─ androidMain (Android platform)
|
|
│ └─ jvmMain (Desktop platform)
|
|
└─ iosMain (iOS platform)
|
|
├─ iosX64Main
|
|
├─ iosArm64Main
|
|
└─ iosSimulatorArm64Main
|
|
```
|
|
|
|
**Key Dependencies per Source Set:**
|
|
- **commonMain**: secp256k1-kmp, kotlinx.coroutines, collection, immutable collections
|
|
- **jvmAndroid**: jackson, okhttp, url-detector, rfc3986
|
|
- **androidMain**: secp256k1-kmp-jni-android, lazysodium-android, jna (aar)
|
|
- **jvmMain**: secp256k1-kmp-jni-jvm, lazysodium-java, jna (jar)
|
|
|
|
### :commons Source Sets
|
|
```
|
|
commonMain (base UI)
|
|
└─ jvmAndroid (shared JVM UI)
|
|
├─ androidMain (Android UI utilities)
|
|
└─ jvmMain (Desktop UI utilities)
|
|
```
|
|
|
|
**Key Dependencies per Source Set:**
|
|
- **commonMain**: Compose Multiplatform, Material3, :quartz
|
|
- **jvmAndroid**: url-detector
|
|
- **androidMain**: AndroidX Compose tooling
|
|
- **jvmMain**: Compose Desktop
|
|
|
|
## Critical Dependency Patterns
|
|
|
|
### 1. secp256k1 Variants
|
|
```kotlin
|
|
// commonMain - API only
|
|
api(libs.secp256k1.kmp.common)
|
|
|
|
// androidMain - JNI Android
|
|
api(libs.secp256k1.kmp.jni.android)
|
|
|
|
// jvmMain - JNI JVM
|
|
implementation(libs.secp256k1.kmp.jni.jvm)
|
|
```
|
|
**Why:** Different JNI bindings for Android vs Desktop JVM
|
|
|
|
### 2. JNA Variants (for LibSodium)
|
|
```kotlin
|
|
// androidMain
|
|
implementation("com.goterl:lazysodium-android:5.2.0@aar")
|
|
implementation("net.java.dev.jna:jna:5.18.1@aar")
|
|
|
|
// jvmMain
|
|
implementation(libs.lazysodium.java)
|
|
implementation(libs.jna) // JAR variant
|
|
```
|
|
**Why:** Android needs AAR packaging, JVM needs JAR
|
|
|
|
### 3. Compose Alignment
|
|
```kotlin
|
|
// commons/build.gradle.kts
|
|
implementation(compose.ui) // Compose Multiplatform BOM
|
|
implementation(compose.material3)
|
|
|
|
// Version catalog alignment
|
|
composeMultiplatform = "1.9.3"
|
|
composeBom = "2025.12.01" // AndroidX Compose
|
|
```
|
|
**Why:** Two Compose ecosystems (Multiplatform + AndroidX) must align
|
|
|
|
## Dependency Configuration Types
|
|
|
|
### API vs Implementation
|
|
|
|
**Use `api` when:**
|
|
- Dependency types appear in module's public API
|
|
- Used in expect/actual declarations visible to consumers
|
|
- Example: `secp256k1-kmp-common` in quartz (public types)
|
|
|
|
**Use `implementation` when:**
|
|
- Internal implementation detail
|
|
- Not exposed to module consumers
|
|
- Example: `okhttp` in quartz (internal network client)
|
|
|
|
### Example from quartz
|
|
```kotlin
|
|
// Public API - exposed to consumers
|
|
api(libs.secp256k1.kmp.common)
|
|
api(libs.jackson.module.kotlin) // Event serialization public
|
|
|
|
// Internal implementation
|
|
implementation(libs.okhttp)
|
|
implementation(libs.kotlinx.coroutines.core)
|
|
```
|
|
|
|
## Transitive Dependency Impact
|
|
|
|
### When :desktopApp depends on :commons
|
|
- Gets `:quartz` transitively (via :commons)
|
|
- Gets `secp256k1-kmp-jvm` transitively (via :quartz jvmMain)
|
|
- Does NOT get Android-specific dependencies (scoped to androidMain)
|
|
|
|
### When :amethyst depends on :commons
|
|
- Gets `:quartz` transitively (via :commons)
|
|
- Gets `secp256k1-kmp-jni-android` transitively (via :quartz androidMain)
|
|
- Does NOT get JVM/Desktop-specific dependencies (scoped to jvmMain)
|
|
|
|
## Verifying Dependencies
|
|
|
|
### Check Module Dependencies
|
|
```bash
|
|
./gradlew :desktopApp:dependencies
|
|
./gradlew :amethyst:dependencies
|
|
```
|
|
|
|
### Check Specific Library
|
|
```bash
|
|
./gradlew dependencyInsight --dependency secp256k1
|
|
./gradlew dependencyInsight --dependency compose-ui
|
|
```
|
|
|
|
### Visualize with Build Scan
|
|
```bash
|
|
./gradlew :desktopApp:dependencies --scan
|
|
# Opens interactive dependency graph in browser
|
|
```
|
|
|
|
## Common Dependency Issues
|
|
|
|
### Issue 1: Wrong secp256k1 Variant in Desktop
|
|
**Symptom:** `UnsatisfiedLinkError: no secp256k1jni in java.library.path`
|
|
**Cause:** Desktop using Android JNI variant
|
|
**Fix:** Ensure jvmMain uses `secp256k1-kmp-jni-jvm`
|
|
|
|
### Issue 2: Compose Version Mismatch
|
|
**Symptom:** `IllegalStateException: Version mismatch`
|
|
**Cause:** Compose Multiplatform plugin vs runtime version mismatch
|
|
**Fix:** Align `composeMultiplatform` version in libs.versions.toml with Kotlin plugin
|
|
|
|
### Issue 3: Duplicate JNA Classes
|
|
**Symptom:** `DuplicateClassException: com.sun.jna.Native`
|
|
**Cause:** Both JAR and AAR JNA variants in classpath
|
|
**Fix:** Use AAR (@aar) in androidMain, JAR in jvmMain (never in shared source sets)
|