247 lines
6.5 KiB
Markdown
247 lines
6.5 KiB
Markdown
# Fahrtenbuch - Multi-Target Scala.js Application
|
|
|
|
A collaborative trip tracking application built with Scala.js, supporting both browser and Node.js environments with real-time peer-to-peer synchronization.
|
|
|
|
## Architecture
|
|
|
|
This project uses a multi-target architecture with shared business logic and platform-specific implementations:
|
|
|
|
```
|
|
fahrtenbuch/
|
|
├── shared/ # Shared business logic and models
|
|
│ └── src/main/scala/fahrtenbuch/
|
|
│ ├── model/ # Data models (Entry, EntryId)
|
|
│ ├── core/ # Business logic (EntryManager)
|
|
│ ├── storage/ # Storage interface
|
|
│ └── sync/ # Synchronization interface
|
|
├── browser/ # Browser-specific implementation
|
|
│ └── src/main/scala/fahrtenbuch/
|
|
│ ├── components/ # Laminar UI components
|
|
│ ├── storage/ # Dexie (IndexedDB) storage
|
|
│ ├── sync/ # Trystero (WebRTC) sync
|
|
│ └── BrowserMain.scala
|
|
├── nodejs/ # Node.js-specific implementation
|
|
│ └── src/main/scala/fahrtenbuch/
|
|
│ ├── storage/ # File system storage
|
|
│ ├── sync/ # WebSocket sync
|
|
│ └── NodeMain.scala
|
|
└── dist/ # Build outputs
|
|
├── browser/ # Browser build artifacts
|
|
└── nodejs/ # Node.js build artifacts
|
|
```
|
|
|
|
## Features
|
|
|
|
### Shared Features
|
|
- **CRDT-based synchronization**: Conflict-free replicated data types ensure consistent state across peers
|
|
- **Real-time sync**: Changes are automatically synchronized between connected peers
|
|
- **Offline support**: Works offline with automatic sync when reconnected
|
|
- **Trip tracking**: Track vehicle trips with distance, cost calculations, and payment status
|
|
|
|
### Browser Features
|
|
- **Modern UI**: Built with Laminar and Bulma CSS framework
|
|
- **IndexedDB storage**: Persistent local storage using Dexie
|
|
- **WebRTC P2P**: Direct peer-to-peer communication via Trystero
|
|
- **Real-time updates**: Live UI updates as data changes
|
|
|
|
### Node.js Features
|
|
- **Command-line interface**: Interactive CLI for managing entries
|
|
- **File system storage**: JSON-based persistent storage
|
|
- **WebSocket server**: Acts as a hub for peer communication
|
|
- **Statistics reporting**: Built-in analytics and reporting
|
|
|
|
## Getting Started
|
|
|
|
### Prerequisites
|
|
- **Scala**: 3.7.1
|
|
- **Node.js**: 16+
|
|
- **sbt**: 1.8+
|
|
|
|
### Installation
|
|
|
|
1. Clone the repository:
|
|
```bash
|
|
git clone <repository-url>
|
|
cd fahrtenbuch
|
|
```
|
|
|
|
2. Install dependencies:
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
3. Build both targets:
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
## Development
|
|
|
|
### Browser Development
|
|
```bash
|
|
# Start development server with hot reload
|
|
npm run dev
|
|
|
|
# Build browser version only
|
|
npm run build:browser
|
|
|
|
# Production build
|
|
npm run build:browser:prod
|
|
```
|
|
|
|
### Node.js Development
|
|
```bash
|
|
# Build Node.js version
|
|
npm run build:nodejs
|
|
|
|
# Run Node.js application
|
|
npm run start:nodejs
|
|
|
|
# With custom options
|
|
node dist/nodejs/main.js --port 8080 --data-dir ./data
|
|
```
|
|
|
|
### SBT Commands
|
|
```bash
|
|
# Compile shared code
|
|
sbt sharedJs/compile
|
|
|
|
# Fast build for browser
|
|
sbt browser/fastOptJS
|
|
|
|
# Optimized build for browser
|
|
sbt browser/fullOptJS
|
|
|
|
# Fast build for Node.js
|
|
sbt nodejs/fastOptJS
|
|
|
|
# Optimized build for Node.js
|
|
sbt nodejs/fullOptJS
|
|
|
|
# Build everything
|
|
sbt compile
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Browser Application
|
|
|
|
1. Build and start the browser version:
|
|
```bash
|
|
npm run build:browser
|
|
npm run dev
|
|
```
|
|
|
|
2. Open your browser and navigate to the displayed URL
|
|
3. Share the URL (including the hash) with other users for real-time collaboration
|
|
|
|
### Node.js Application
|
|
|
|
1. Build and start the Node.js version:
|
|
```bash
|
|
npm run build:nodejs
|
|
node dist/nodejs/main.js --port 8080
|
|
```
|
|
|
|
2. Use the interactive CLI:
|
|
```
|
|
fahrtenbuch> help
|
|
fahrtenbuch> add 1000 1050 John Dog
|
|
fahrtenbuch> list
|
|
fahrtenbuch> stats
|
|
fahrtenbuch> peers
|
|
```
|
|
|
|
3. Connect multiple instances:
|
|
```bash
|
|
# Start first instance
|
|
node dist/nodejs/main.js --port 8080
|
|
|
|
# Start second instance and connect to first
|
|
node dist/nodejs/main.js --port 8081 --connect localhost:8080
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Node.js Options
|
|
- `--port <port>`: WebSocket server port (default: 8080)
|
|
- `--data-dir <dir>`: Data storage directory (default: ./data)
|
|
- `--connect <host:port>`: Connect to peer at host:port
|
|
- `--help`: Show help message
|
|
|
|
### Browser Configuration
|
|
The browser version uses URL fragments for room identification. Users sharing the same URL fragment will be connected in the same sync room.
|
|
|
|
## Data Model
|
|
|
|
### Entry
|
|
Each trip entry contains:
|
|
- `id`: Unique identifier
|
|
- `startKm`: Starting odometer reading
|
|
- `endKm`: Ending odometer reading
|
|
- `driver`: Driver name
|
|
- `animal`: Animal transported
|
|
- `paid`: Payment status
|
|
- `date`: Entry creation date
|
|
- `gasPricePerKm`: Gas cost per kilometer
|
|
- `wearPricePerKm`: Wear cost per kilometer
|
|
|
|
### Synchronization
|
|
- Uses CRDT (Conflict-free Replicated Data Types) for conflict resolution
|
|
- Last-writer-wins semantics for most fields
|
|
- Automatic merging of concurrent updates
|
|
- Peer-to-peer synchronization without central server
|
|
|
|
## Storage
|
|
|
|
### Browser Storage
|
|
- **IndexedDB**: Via Dexie library
|
|
- **Schema versioning**: Automatic migrations
|
|
- **Live queries**: Real-time UI updates
|
|
|
|
### Node.js Storage
|
|
- **File system**: JSON files in data directory
|
|
- **Atomic writes**: Safe concurrent access
|
|
- **Backup friendly**: Human-readable JSON format
|
|
|
|
## Networking
|
|
|
|
### Browser Networking
|
|
- **WebRTC**: Direct peer-to-peer via Trystero
|
|
- **TURN/STUN**: Configurable relay servers
|
|
- **Room-based**: URL hash determines sync room
|
|
|
|
### Node.js Networking
|
|
- **WebSocket**: Server-client architecture
|
|
- **Auto-discovery**: Automatic peer detection
|
|
- **Hub model**: Can act as relay for browser clients
|
|
|
|
## Development Tips
|
|
|
|
### Adding New Features
|
|
1. Add shared logic to `shared/src/main/scala/fahrtenbuch/`
|
|
2. Implement platform-specific parts in `browser/` and `nodejs/`
|
|
3. Update interfaces in `storage/` and `sync/` packages
|
|
4. Test both targets with `npm run build`
|
|
|
|
### Debugging
|
|
- Browser: Use browser dev tools, network tab for WebRTC
|
|
- Node.js: Use `console.log` or Node.js debugging tools
|
|
- Storage: Check browser IndexedDB or Node.js data directory
|
|
|
|
### Performance
|
|
- Use `fullOptJS` for production builds
|
|
- Browser builds are optimized for incremental loading
|
|
- Node.js builds are optimized for startup time
|
|
|
|
## Contributing
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch
|
|
3. Make changes to shared code and both platform implementations
|
|
4. Test both browser and Node.js targets
|
|
5. Submit a pull request
|
|
|
|
## License
|
|
|
|
[Add your license here]
|