feat(update-seam): first-class update operation through the provider seam
Brainy's planner emits a single UpdateInMetadataIndexOperation / UpdateVerbInGraphIndexOperation when the registered provider announces the `update-op` capability (capabilities has 'update-op' AND the method exists — both halves), and the legacy remove+add pair otherwise. A provider whose capability set claims what the instance lacks is refused at registration with a typed ProviderCapabilityMismatchError — never a silent fallback. - MetadataIndexProvider.updateIndex(id, before, after, generation?) and GraphIndexProvider.updateVerb(id, before, after, generation) — optional, rollback symmetric by construction (update(a,b) undone by update(b,a)). - Emission at update(), planTxUpdate() and updateRelation()'s graph leg. - transact() gains op:'updateRelation' (TxUpdateRelationOperation), born batchable; updateRelation()'s record build is shared with the planner. - Both paths live for one overlap release; the pair path retires with the provider-side compensation layer in the following cut. Pinned in tests/integration/update-op-emission.test.ts (7 pins).
This commit is contained in:
parent
7c8c8be30c
commit
0c028dfc81
11 changed files with 1090 additions and 66 deletions
|
|
@ -848,6 +848,7 @@ const db = await brain.transact([
|
|||
{ op: 'add', id: orderId, type: NounType.Document, subtype: 'order', data: 'Order #1042' },
|
||||
{ op: 'update', id: customerId, metadata: { lastOrderAt: Date.now() }, ifRev: customer._rev },
|
||||
{ op: 'relate', from: customerId, to: orderId, type: VerbType.Creates, subtype: 'purchase' },
|
||||
{ op: 'updateRelation', id: purchaseRelationId, subtype: 'return' },
|
||||
{ op: 'remove', id: staleDraftId },
|
||||
{ op: 'unrelate', id: oldRelationId }
|
||||
], {
|
||||
|
|
@ -864,6 +865,7 @@ db.receipt.generation // the committed generation
|
|||
- `{ op: 'update', ... }` — same parameters as `update()`, including per-entity `ifRev` CAS
|
||||
- `{ op: 'remove', id }` — deletes the entity plus its relationships (same cascade as `delete()`)
|
||||
- `{ op: 'relate', ... }` — same parameters as `relate()`, including `bidirectional`; duplicates dedupe to the existing relationship id
|
||||
- `{ op: 'updateRelation', ... }` — same parameters as `updateRelation()`; a batchable, first-class relationship update (not `unrelate` + `relate` — the relationship id and its edge never change)
|
||||
- `{ op: 'unrelate', id }` — deletes a relationship by id
|
||||
|
||||
Operations may reference ids created earlier in the same batch.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue