locorda_dev
Unified development tooling for Locorda applications. Add this single package as a dev_dependency to activate all Locorda build-time code generators and deployment tools.
Features
- π§ Automatic CRDT Mapping Generation - Generate merge strategy documents from annotations
- π¦ Bootstrap Aggregation - Embed mappings for offline-first cold start
- π Web Worker Compilation - Build worker isolates for web platform
- πΊοΈ RDF Mapper Generation - Dart β RDF serialization code
- π Deployment Tool - Split and deploy CRDT mappings to CDN/server
Installation
# For Dart projects
dart pub add dev:build_runner dev:locorda_dev
# For Flutter projects
flutter pub add dev:build_runner dev:locorda_dev
Usage
1. Code Generation (build_runner)
The locorda_dev package automatically activates all Locorda builders when you run build_runner:
# Development mode with watch
dart run build_runner watch
# One-time build
dart run build_runner build
# Clean build (removes cached artifacts)
dart run build_runner build --delete-conflicting-outputs
What gets generated:
lib/**/*.crdt.cache.trig- CRDT mapping documents (build cache)lib/src/generated/mapping_bootstrap.g.dart- Embedded mappings listlib/**/*.rdf_mapper.g.dart- RDF serialization codelib/init_locorda.g.dart- Convenience initializationlib/locorda_config.g.dart- Resource configurationweb/worker.dart.js- Web worker bundle (for Flutter web apps)
2. Deploying CRDT Mappings
After code generation, deploy your CRDT mapping documents to make them accessible at their canonical URIs:
# Deploy to local directory
dart run locorda_dev:deploy_mappings dist/mappings/
# Then upload to your CDN/server
aws s3 sync dist/mappings/ s3://myapp.example.com/mappings/ --acl public-read
# or
rsync -av dist/mappings/ user@server.com:/var/www/mappings/
Why deploy?
- Makes mappings discoverable by other apps
- Enables cross-app collaboration with shared merge strategies
- Allows HTTP access for validation and debugging
Output format:
dist/mappings/
βββ note-v1.ttl
βββ category-v1.ttl
βββ core-v1.ttl
Each file contains a single CRDT mapping document in Turtle format, ready to serve at its canonical IRI.
Important: Each mapping IRI must produce a unique filename. If two different IRIs would produce the same filename (e.g., https://a.com/note-v1# and https://b.com/note-v1# both produce note-v1.ttl), deployment will fail. This ensures the IRIβURL mapping remains valid.
3. Custom Bootstrap File Location
If your bootstrap file is not at the default location:
dart run locorda_dev:deploy_mappings dist/mappings/ lib/custom/bootstrap.g.dart
Common Workflows
Initial Setup
# 1. Add dev dependency
flutter pub add dev:locorda_dev dev:build_runner
# 2. Annotate your models
# (See locorda_annotations documentation)
# 3. Generate code
dart run build_runner build
# 4. Deploy mappings (production)
dart run locorda_dev:deploy_mappings dist/mappings/
Development Cycle
# Keep watch running during development
dart run build_runner watch
# In another terminal, run your app
flutter run
CI/CD Pipeline
# .github/workflows/deploy.yml
- name: Generate code
run: dart run build_runner build --delete-conflicting-outputs
- name: Deploy CRDT mappings
run: |
dart run locorda_dev:deploy_mappings dist/mappings/
aws s3 sync dist/mappings/ s3://${{ secrets.BUCKET }}/mappings/
Builders Included
locorda_dev applies these builders via applies_builders:
crdt_mapping_generator
Generates CRDT mapping documents from @RootResource annotations with @CrdtLwwRegister, @CrdtOrSet, @CrdtImmutable on properties.
Input: lib/**/*.dart with annotated classes
Output: lib/**/*.crdt.cache.trig (build cache)
mapping_bootstrap
Aggregates generated CRDT mappings and manual assets into a single List<String> constant for offline-first bootstrap.
Input: Cache files + assets/contracts/mappings/**/*.ttl
Output: lib/src/generated/mapping_bootstrap.g.dart
rdf_mapper_generator
Generates Dart β RDF serialization code from RDF mapping annotations.
Input: lib/**/*.dart with @RdfProperty annotations
Output: lib/**/*.rdf_mapper.g.dart, lib/init_rdf_mapper.g.dart
web_worker
Compiles worker isolate to JavaScript for web platform.
Input: lib/worker.dart
Output: web/worker.dart.js
init_locorda_generator
Generates convenience initialization wrapper with discovered resources.
Input: pubspec.yaml
Output: lib/init_locorda.g.dart
locorda_config_generator
Extracts resource configuration from annotations for sync setup.
Input: pubspec.yaml + annotated classes
Output: lib/locorda_config.g.dart
Configuration
Custom Mapping Asset Locations
Add build.yaml to your project root:
targets:
$default:
builders:
locorda_mapping_bootstrap_generator:mapping_bootstrap:
options:
mapping_roots:
- assets/contracts/mappings # Default
- assets/custom/rdf # Additional location
Disable Specific Builders
targets:
$default:
builders:
locorda_dev:locorda_dev:
enabled: false # Disables all locorda_dev builders
Troubleshooting
Build Fails with "No suitable constructor found"
Clean build cache and regenerate:
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs
Generated Files Not Updating
Ensure watch mode is running or force full rebuild:
dart run build_runner build --delete-conflicting-outputs
Empty bootstrapMappings List
- Check that
@RootResourcehascrdt.generate == true(default) - Verify CRDT annotations exist on properties
- Clean and rebuild
- Check
lib/**/*.crdt.cache.trigfiles exist in.dart_tool/build/
Deploy Tool Shows "Bootstrap file not found"
Ensure you've run build_runner first:
dart run build_runner build
dart run locorda_dev:deploy_mappings dist/mappings/
Filename Collision Error
If deployment fails with "Filename collision detected":
- Two different mapping IRIs are producing the same filename
- This breaks the IRIβURL principle - fix your mapping IRIs
- Use more specific path segments:
// Bad: Both produce note-v1.ttl MergeContract('https://app-a.com/mappings/note-v1#') MergeContract('https://app-b.com/mappings/note-v1#') // Good: Unique filenames MergeContract('https://app-a.com/mappings/app-a-note-v1#') // app-a-note-v1.ttl MergeContract('https://app-b.com/mappings/app-b-note-v1#') // app-b-note-v1.ttl
CRDT Mappings Not Generating
Check your annotations:
@RootResource(
IriTerm('https://schema.org/Note'),
MergeContract('https://myapp.example.com/mappings/note-v1#'), // Must have this
)
class Note {
@RdfProperty(Schema.name)
@CrdtLwwRegister() // CRDT annotation required
String? title;
}
Package Structure
locorda_dev/
βββ bin/
β βββ deploy_mappings.dart # CLI tool for deployment
βββ lib/
β βββ builder.dart # Meta-builder (applies other builders)
β βββ locorda_dev.dart # Package documentation
βββ test/
βββ deploy_mappings_test.dart
See Also
- locorda_annotations - Annotation reference
- locorda_init_generator - Generator implementation
- Concept: CRDT Mapping Generation
- Example: personal_notes_app - Complete example
License
See LICENSE in the repository root.
Libraries
- builder
- Build-time integration for Locorda dev tools.
- locorda_dev
- Locorda Dev - unified build-time tools for Locorda applications.