DelveTalknot logged in

cistern

v.0

Cistern

Law

law owner: (request.kind == 0) or (request.subject == "did:plc:6amo7col5h4ciq2gpm5eur7b")

Source varat-vusit

44 lines of Objective Bend
edition ObjectiveBend 1
import ./Abi.obend as Abi
import ./List.obend as Lists
import ./Document.obend as Document
import ./Plan.obend as Plans
import ./World.obend as World
import ./Card.obend as Card
import ./Relation.obend as Relations
import ./Text.obend as Text
# A retained receipt, keyed {at, slot}: `at` is the receipt's height, so key order is the order
# of the turns, and past 256 the host drops the oldest.
record Kept:
  at: Nat
  slot: Plans.Slot
  outcome: Plans.Outcome
record State:
  entries: Relations.Relation<Kept>
def initial() -> State:
  {entries: Relations.empty()}
def relations() -> Relations.Decls:
  Lists.append(Relations.Decls.nil(), {field: "entries", key: Text.words("at slot"), limit: 256n})
# Retains a refusal (or any) receipt; the answer is how many it keeps.
def retain(state: State, input: {receipt: Plans.Receipt}, context: Abi.Context) -> Activity<Nat>:
  let written(_) = write {entries: insert {at: input.receipt.height, slot: input.receipt.slot, outcome: input.receipt.outcome}}
  Relations.count(Relations.insert(state.entries, {at: input.receipt.height, slot: input.receipt.slot, outcome: input.receipt.outcome}, keptKey))
def keptKey(kept: Kept) -> {at: Nat, slot: Plans.Slot}:
  {at: kept.at, slot: kept.slot}
# A receipt is structured data, not a spell: the card offers no form.
def methods() -> Lists.List<String>:
  Text.words("retain")
def forms() -> Card.Forms:
  Card.Forms.nil()
def blurb() -> Card.Door:
  {word: "cistern", blurb: "Keeps the receipts it is given, newest first."}
def receive(state: State, input: Card.Reply, context: Abi.Context) -> Activity<Card.Replied>:
  Card.answer(input, context, forms(), render(state, context))
def outcomeName(outcome: Plans.Outcome) -> String:
  match outcome:
    case admitted(_): "admitted"
    case refused(r): "refused {r.class}"
def line(kept: Kept) -> Document.Document:
  Document.text("#{natText(kept.at)} {Card.handle(kept.slot.principal)}: {outcomeName(kept.outcome)}\n")
def render(state: State, context: Abi.Context) -> Document.Document:
  Document.Document.sequence({items: Document.Documents.cons({head: Document.text("Cistern\n"), tail: Card.clipped(Lists.map(Lists.reverse(Relations.rows(state.entries)), line), 8n)})})

Ledger

  1. ◦ createdht.13homik-kakafgenesis-cistern · did:plc:6amo7col5h4ciq2gpm5eur7b