Document Plugin
Status: Stable – limited-scope mutation helper
Import identifier in policy expressions:
@DocumentPlugin.*
The Document Plugin is a surgical on‑chain helper that lets Tarobase policies update a single field in an existing document without rewriting the whole record. It is intentionally narrow in scope to preserve Tarobase’s immutability‑by‑default philosophy—use it sparingly and only when a true mutable counter/state flag is essential.
Transactional functions
updateField
@DocumentPlugin.updateField(path, field, value)
Parameter | Type | Description |
---|---|---|
path | String | Absolute document path to modify (e.g. /forumPosts/$postId ). Must point to an on‑chain collection. |
field | String | Field name to update. The field must already exist and be declared in the collection’s fields map. |
value | Any | New value expression. Can reference getAfter() or other plugin calls. |
- The call writes on-chain in the same atomic transaction as the enclosing hook.
- Reverts if the document does not exist, the field isn’t declared, or type mismatches.
Important: Use strong authorization in the surrounding
rules.*
to restrict who may trigger a hook containingupdateField
.
Usage patterns
1. Incrementing a view counter (server‑side only)
"forumPosts/$postId": {
"fields": { "views": "UInt" },
"rules": { "update": "false" },
"hooks": {
"onchain": {
// Only the SERVER_ADMIN_ADDRESS may record a view event
"update": "@user.address == @constants.SERVER_ADMIN_ADDRESS && @DocumentPlugin.updateField(/forumPosts/$postId, 'views', getAfter(/forumPosts/$postId).views + 1)"
}
}
}
2. Marking a lobby as completed & stamping the winner
"lobbies/$lobbyId": {
"fields": { "state": "String", "winner": "Address?" },
"rules": { "update": "@user.address == @constants.SERVER_ADMIN_ADDRESS" },
"hooks": {
"onchain": {
"update": "@DocumentPlugin.updateField(/lobbies/$lobbyId, 'state', 'completed') && @DocumentPlugin.updateField(/lobbies/$lobbyId, 'winner', @newData.winner)"
}
}
}
Both updates happen atomically in the same transaction.
Best practices & cautions
- Prefer immutability: only introduce mutable fields (counters, flags) when absolutely required.
- Lock down access with explicit checks: typically
@user.address == @constants.SERVER_ADMIN_ADDRESS
. - Keep updates idempotent where possible to avoid race conditions.
- If you need to update multiple fields, chain multiple
updateField
calls with&&
. - Cannot create new documents or new fields—only modifies existing declared fields.
- Works only on on‑chain collections; off‑chain docs use standard database updates instead.