Keep collaboration, undo and history on the resource path
tilo-app new shared-list --from-example shared-checklist
cd shared-list
tilo-app test
The app starts empty and uses shared controls, theme values and Fluent labels.
Read src/lib.rs for the model and tests/app.rs for executable examples.
Without creating a project, retrieve just either file with
tilo-app examples shared-checklist --file tests/app.rs --json (or
--file src/lib.rs). This guide also answers tilo-app guide undo,
guide history and guide sync, including --json.
Put durable fields in the Model resource and edits in #[action] methods.
Bind controls to generated descriptors through ViewCx. One action becomes
one attributed version and undo step; a bulk operation belongs in one action.
Use Collection item ids from ActionCx::id() so an edit follows its item.
String fields merge concurrent text edits; booleans and numbers resolve as
registers. Put visual caches and participant-local state outside the shared
model. External effects need their own effect contract; replaying a resource
edit must not repeat a network request or file write.
The example’s production-path tests show what to assert:
concurrent_adds_keep_both_items: forkReplica<Checklist>, give the two replicas differentas_authorvalues, apply edits andsync_withthe peer. Check both items survive and both states agree.undo_takes_back_only_my_own_actions: invoke the action throughTestApp, merge a peer edit and check the rendered result. Undo removes the local action while retaining the peer’s item; redo restores the local action.history_is_attributed: inspectReplica::versions()and check the author and action summary. Use host-provided identity in the running app.
The resource runtime supplies storage, history, per-author undo and merge semantics. On Tilo, workspace collaborators and roles govern access; agents use the same permission-filtered resource/action door as other collaborators. Device delivery uses the host’s collaboration transport. Replica tests prove merge behavior; sign-in, authorization and delivery between actual devices still need host integration tests. They do not require an app-local database, undo stack, identity service or sync loop.
Evolve an existing resource
Changing a Rust field type does not convert documents stored on other
devices. Collection<T> stores a map keyed by item id, with order keys and
item values; an Automerge list at that path is a different storage shape.
An absent collection reads as empty. An expected a collection error means
a present value has the wrong shape: inspect its actual type and conflicts
before changing it. Keep the retained document; do not replace it with defaults.
Declare #[resource(version = N, migrate = path)] when changing the storage
schema. The migration receives the document and prior version. Preserve
item ids, values and order while converting the known old shape. The runtime
runs the callback on a fork and applies the housekeeping change only if it
succeeds. Test an actual old document, migration failure leaving it unchanged,
and a second open preserving the migrated content. A fresh empty app test does
not exercise an upgrade.
Next: tilo-app guide actions to expose the capability or guide verify to
inspect its public surface.
More: Templates and examples,
A resource workflow.
This page is docs/developers/tasks/collaborate.md in the Tilo repository, at 29fbb80121. Changes to it are made there.