Several orbitals, standard behaviors composed in, pages linked together and events wiring them up.
A real app is several orbitals: each owns its data and screens, and they talk only through events. This tutorial assembles a small library system from the pieces the earlier pages built.
| Orbital | Owns | Talks |
|---|---|---|
Shelf | the books and a lending screen | emits BOOK_LENT |
Loans | the loan log | listens for BOOK_LENT |
1app library "1.0.0"
2"A small library: a shelf composed from the standard library, and a loan log that listens to it."
3orbital Shelf {
4 entity ShelfBook [persistent: shelf_books, local] {
5 id : string!
6 name : string!
7 author : string = ""
8 instances [
9 { id: "B-1", name: "Communicating Sequential Processes", author: "Hoare" },
10 { id: "B-2", name: "The Art of Computer Programming", author: "Knuth" }
11 ]
12 }
13
14 trait Lending -> ShelfBook [interaction, instance] {
15 initial: idle
16
17 state idle {
18 INIT -> idle
19 (render-ui main { type: stack, direction: vertical, gap: sm, children: [
20 { type: typography, content: "Lend a book", variant: h3 },
21 { type: button, label: "Lend Hoare", action: LEND, actionPayload: { title: "Communicating Sequential Processes" }, variant: primary },
22 { type: button, label: "See loans", href: "/loans", variant: link }
23 ] })
24 LEND -> idle
25 (emit BOOK_LENT { title: ?title })
26 }
27
28 emits {
29 BOOK_LENT -> external {
30 title : string!
31 }
32 }
33
34 listens {
35 LEND {
36 title : string!
37 }
38 }
39 }
40
41 page "/shelf" -> Lending
42}
43
44orbital Loans {
45 entity Loan [runtime] {
46 id : string!
47 last : string = ""
48 }
49
50 trait LoanLog -> Loan [interaction, instance] {
51 initial: idle
52
53 state idle {
54 INIT -> idle
55 (render-ui main { type: stack, direction: vertical, gap: sm, children: [
56 { type: typography, content: (if (= @entity.last "") "No loans yet." (str/concat "Last loan: " @entity.last)), variant: body },
57 { type: button, label: "Back to the shelf", href: "/shelf", variant: link }
58 ] })
59 LENT -> idle
60 (set @entity.last ?title)
61 (notify success (str/concat "Lent: " ?title))
62 }
63
64 listens {
65 Shelf.Lending.BOOK_LENT -> LENT
66 LENT {
67 title : string!
68 }
69 }
70 }
71
72 page "/loans" -> LoanLog
73}orb validate library.lolo
orb verify library.lolo --allValidation proves the wiring: BOOK_LENT is declared external with a payload, the loan log listens with the qualified source, both pages link to each other, and each renders something. Verification plays it in all three engines.
Swap the hand-written shelf screen for std-browse bound to ShelfBook (see composition), add std-modal for a lending form, and give the loans a stored entity. Each step keeps the same rule: compose a behavior, bind it, react to its events with a sibling trait.
orb compile library.lolo --output ./library-appThe result is a full TypeScript application. Because the books are browser-stored, the client build alone runs it: orb compile library.lolo --mode client produces a static site.
A programming language of composable state machines.