Developer documentation for the UbiCity modules.
UbiCity is implemented in (compiles to JavaScript). All modules are in
src-/ and compile to *.res.js files.
UbiCity.res - Core domain types ├── Decoder.res - JSON validation ├── Mapper.res - Data indexing and queries ├── Analysis.res - Pattern detection ├── Privacy.res - Anonymization tools ├── Export.res - Data export formats ├── Visualization.res - HTML generation ├── Capture.res - CLI capture logic └── CaptureCLI.res - CLI entry point
type t = {
latitude: float,
longitude: float,
}
let make: (~latitude: float, ~longitude: float) => option<t>
let isValid: t => bool
type t = {
name: string,
coordinates: option<Coordinates.t>,
type_: option<string>,
address: option<string>,
}
let make: (
~name: string,
~coordinates: option<Coordinates.t>=?,
~type_: option<string>=?,
~address: option<string>=?,
unit,
) => result<t, string>
type t = {
id: string,
name: option<string>,
interests: option<array<string>>,
}
let make: (
~id: string,
~name: option<string>=?,
~interests: option<array<string>>=?,
unit,
) => result<t, string>
type t = {
id: string,
timestamp: string,
version: string,
learner: Learner.t,
context: Context.t,
experience: ExperienceData.t,
privacy: Privacy.t,
tags: option<array<string>>,
}
let generateId: unit => string
let make: (
~id: option<string>=?,
~timestamp: option<string>=?,
~learner: Learner.t,
~context: Context.t,
~experience: ExperienceData.t,
~privacy: option<Privacy.t>=?,
~tags: option<array<string>>=?,
~version: option<string>=?,
unit,
) => t
import { captureExperience } from './src-/Mapper.res.js';
const result = await captureExperience(mapper, experience);
// Returns: Ok(experienceId) | Error(message)// Get all experiences
const allExperiences = await loadAll(mapper);
// Get by location
const labExperiences = getByLocation(mapper, "Lab A");
// Get by domain
const roboticsExperiences = getByDomain(mapper, "robotics");
// Get by learner
const aliceExperiences = getByLearner(mapper, "alice-maker");
// Identify hotspots
const hotspots = identifyHotspots(mapper);import { TemporalAnalyzer } from './src-/Analysis.res.js';
// Analyze by time of day
const byTime = TemporalAnalyzer.analyzeByTimeOfDay(experiences);
// Returns: { morning: 5, afternoon: 3, evening: 2, night: 1 }
// Analyze by day of week
const byDay = TemporalAnalyzer.analyzeByDayOfWeek(experiences);
// Detect learning streaks
const streaks = TemporalAnalyzer.detectStreaks(experiences, 7);
// Returns: [{ startDate, endDate, dayCount, experienceCount }]import { CollaborativeNetworkAnalyzer } from './src-/Analysis.res.js';
const network = CollaborativeNetworkAnalyzer.buildCollaborationNetwork(experiences);
// Returns: { nodes: [{id, size}], edges: [{source, target, weight}] }import { RecommendationEngine } from './src-/Analysis.res.js';
// Similar learners
const similar = RecommendationEngine.recommendSimilarLearners(
experiences,
"alice-maker",
5 // top 5
);
// Recommended locations
const locations = RecommendationEngine.recommendLocations(
experiences,
"alice-maker",
5
);
// Recommended domains
const domains = RecommendationEngine.recommendDomains(
experiences,
"alice-maker",
5
);import {
anonymizeLearner,
anonymizeLocation,
fullyAnonymize
} from './src-/Privacy.res.js';
// Anonymize learner ID
const anon = anonymizeLearner(experience, {
hashId: true,
removeInterests: true
});
// Anonymize location (GPS fuzzing)
const anonLocation = anonymizeLocation(experience, {
fuzzCoordinates: true,
removeAddress: true
});
// Full anonymization
const fully = fullyAnonymize(experience);import { removePII, sanitizeText } from './src-/Privacy.res.js';
// Remove emails, phone numbers, URLs from text
const cleaned = sanitizeText("Contact me at alice@example.com or 555-1234");
// Returns: "Contact me at [EMAIL] or [PHONE]"
// Remove PII from entire experience
const cleaned = removePII(experience);import { exportToCSV } from './src-/Export.res.js';
const csv = exportToCSV(experiences);
// Returns CSV string with proper escapingimport { exportToGeoJSON } from './src-/Export.res.js';
const geojson = exportToGeoJSON(experiences);
// Returns RFC 7946 compliant GeoJSON FeatureCollectionimport { exportToDOT } from './src-/Export.res.js';
const network = { nodes: [...], edges: [...] };
const dot = exportToDOT(network);
// Returns: "digraph G { ... }"
// Visualize with: dot -Tpng domains.dot -o domains.pngimport { exportJourneysToMarkdown } from './src-/Export.res.js';
const markdown = exportJourneysToMarkdown(experiences);
// Returns learner journey timelines in Markdown formatimport { exportData } from './src-/Export.res.js';
// Auto-routes to appropriate exporter
const data = exportData(experiences, "csv");
const data = exportData(experiences, "geojson");
const data = exportData(experiences, "dot", network);
const data = exportData(experiences, "markdown");
const data = exportData(experiences, "json");import { generateHTML } from './src-/Visualization.res.js';
const html = generateHTML(
summary, // { totalExperiences, uniqueLocations, ... }
hotspots, // [{ location, count, learners, diversity, domains }]
network, // { nodes, edges }
coordsCount // number of locations with GPS
);
// Returns complete HTML document with CSS and JavaScriptimport { decodeExperiences } from './src-/Decoder.res.js';
const rawData = JSON.parse(fs.readFileSync('data.json', 'utf-8'));
const result = decodeExperiences(rawData);
if (result.TAG === "Ok") {
const experiences = result._0;
// Use validated experiences
} else {
console.error("Validation errors:", result._0);
}All validation functions return Result types:
// Result type in compiled JS:
// Ok: { TAG: "Ok", _0: value }
// Error: { TAG: "Error", _0: errorMessage }
const result = Location.make("Lab A");
if (result.TAG === "Ok") {
const location = result._0;
// Success
} else {
const error = result._0;
// Handle error
}UbiCity is written in for type safety. The compiled JavaScript includes runtime checks. Types are validated at: 1. Compile time ( type checker) 2. Runtime (Decoder module for JSON) 3. API boundaries (validation on user input)
See examples/ directory: - populate-examples.js - Sample data
generation - api-usage.js - API usage patterns