Type-safe ReScript implementation of UbiCity core functionality.
Core domain types and functional utilities:
Coordinates- GPS coordinates with validationLocation- Learning locationsLearner- Learner identityContext- WHERE learning happenedExperienceData- WHAT was learnedLearningExperience- Complete learning experience recordPrivacy- Privacy settingsAnalysis- Functional analysis utilities
CLI capture tool for recording learning experiences:
CaptureSession- Interactive capture session- Supports Quick, Full, and Template modes
- Type-safe input validation
- Async/await interface
Urban knowledge mapper for storing and analyzing experiences:
- Storage integration
- Fast lookup indices (location, domain, learner)
- Analysis functions (hotspots, interdisciplinary connections)
- Domain diversity calculations
CLI entry point for the capture tool.
ReScript modules compile to ES6 JavaScript with .res.js extension:
# Compile ReScript to JavaScript
npm run res:build
# Watch mode
npm run res:dev# Quick mode (minimal prompts)
node src-rescript/CaptureCLI.res.js
# Full mode (all optional fields)
node src-rescript/CaptureCLI.res.js full
# Generate template
node src-rescript/CaptureCLI.res.js templateopen UbiCity
// Create a learning experience
let learnerResult = Learner.make(~id="alice", ())
let locationResult = Location.make(~name="City Library", ())
switch (learnerResult, locationResult) {
| (Ok(learner), Ok(location)) => {
let context = Context.make(~location, ())
let experienceResult = ExperienceData.make(
~type_="reading",
~description="Explored urban planning books",
~domains=["architecture", "sociology"],
()
)
switch experienceResult {
| Ok(experience) => {
let learning = LearningExperience.make(
~learner,
~context,
~experience,
()
)
Console.log(learning.id)
}
| Error(err) => Console.error(err)
}
}
| _ => Console.error("Failed to create learner or location")
}// Initialize mapper
let mapper = await Mapper.make(~storageDir="./ubicity-data", ())
// Capture an experience
let result = await Mapper.captureExperience(mapper, learningExperience)
// Find interdisciplinary connections
let connections = Mapper.findInterdisciplinary(mapper)
// Get hotspot locations
let hotspots = Mapper.getHotspots(mapper, ~limit=5, ())
// Calculate domain diversity
let diversity = Mapper.calculateDiversity(mapper)ReScript provides:
- Compile-time type checking - Catch errors before runtime
- Sound type system - No
nullorundefinedsurprises - Pattern matching - Exhaustive error handling
- Immutability - Default immutability prevents bugs
- Interop with JS - Seamless integration with existing JS code
- ✅ Core domain types (UbiCity.res)
- ✅ Capture tool (Capture.res)
- ✅ Mapper (Mapper.res)
- ✅ CLI entry point (CaptureCLI.res)
- ⏳ Storage validation integration
- ⏳ Analysis module (full port)
- ⏳ Visualization module
- ⏳ Privacy module
- ⏳ Export module
ReScript Modules JavaScript Integration
┌─────────────────┐ ┌──────────────────┐
│ UbiCity.res │ │ storage.js │
│ (Domain Types) │ │ (File I/O) │
└────────┬────────┘ └─────────┬────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ Mapper.res │◄──────│ Bindings │
│ (Analysis) │ │ (FFI) │
└────────┬────────┘ └──────────────────┘
│
▼
┌─────────────────┐
│ Capture.res │
│ (CLI Tool) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ CaptureCLI.res │
│ (Entry Point) │
└─────────────────┘
AGPL-3.0-or-later