Podatki, ki jih ima orbital, kje so shranjeni in kdo jih sme brati ali spreminjati.
Entiteta so podatki, ki jih ima orbital. Vsak orbital navede natanko eno glavno entiteto; druga ali tretja kocka entity postane pomožna entiteta istega orbitala. Lastnosti se na entiteto vežejo z ->, berejo in pišejo pa jo prek @entity.
1entity Invoice [persistent: invoices] {
2 id : string!
3 client : string!
4 amount : money = 0
5 status : "draft" | "sent" | "paid" = draft
6 dueOn : date
7 paidAmount : number = derived (if (= @entity.status "paid") @entity.amount 0)
8}! označi obvezno polje, ? polje, ki je lahko prazno.= value določi privzeto vrednost. Privzete vrednosti so izrazi; = now zabeleži čas nastanka."a" | "b" | "c" je zaprt nabor: nastavitev katerekoli druge vrednosti je napaka preverjanja.derived (…) se izračuna iz drugih polj, kadar se spremenijo; nikoli ni shranjeno.Tipi so običajni osnovni (string, number, int, boolean, date, timestamp) in izpopolnjeni tipi, ki se bolje prikažejo in preverijo: money, email, url, phone, file, duration, icon.
Oznaka v oglatih oklepajih pove, kje se hranijo vrstice:
| Oznaka | Pomen |
|---|---|
[runtime] | V pomnilniku, dokler je stran odprta. Stanje prikaza, števci, čarovniki. |
[persistent: invoices] | Shranjene vrstice v imenovani zbirki, bere jih fetch, piše persist. |
[persistent: invoices, local] | Shranjene vrstice v brskalniku obiskovalca (IndexedDB). Aplikacija ne potrebuje strežnika. |
[runtime, shared] | En okvir, ki si ga delijo vse lastnosti, vezane na entiteto, znotraj seje enega obiskovalca. |
[persistent: people, identity] | Ta entiteta je oblika prijavljenega obiskovalca, @user. |
@entity lastnosti so privzete vrednosti entitete, nato shranjena vrstica, na katero je vezana (če obstaja), nato njen lastni okvir, stanje prikaza, ki ga piše (set @entity.x v). Dve lastnosti na isti nedeljeni entiteti nikoli ne vidita zapisov druga druge; ko bi ju morali, entiteto označi s shared.
Entiteta, shranjena v brskalniku, lahko začne z vrsticami. instances jih izpiše, vsaka vrstica pa se preveri glede na polja:
NoteList
on Note · states: 2 · transitions: 4NoteForm
on Note · states: 1 · transitions: 2Zgornji program kot avtomati stanj, eden za vsako lastnost: vsak okvir je stanje, vsaka puščica dogodek, ki ga premakne, ikone na puščici pa so učinki, ki jih ta dogodek izvede. ◇ na puščici je varovalo; z miško pojdite nanj in preberite pogoj. Kako brati AVL
1app std-orb-docex-notes "1.0.0"
2"std-orb-docex-notes — a stored list with a form: the list loads on mount, the form saves a new note, and a listens route reloads the list."
3orbital NotesOrbital {
4 entity Note [persistent: docex_notes, local] {
5 id : string!
6 title : string!
7 body : string = ""
8 instances [
9 { id: "N-1", title: "Read about the closed circuit", body: "Event, guard, transition, effects, UI." },
10 { id: "N-2", title: "Run orb validate", body: "Zero errors and zero warnings is the bar." }
11 ]
12 }
13
14 trait NoteList -> Note [interaction, collection] {
15 initial: loading
16
17 state loading {
18 INIT -> loading
19 (fetch Note { emit: { success: NotesLoaded, failure: NotesFailed } })
20 (render-ui main { type: skeleton, variant: list, rows: 2 })
21 NotesLoaded -> ready
22 (emit MOVED { event: "NotesLoaded" })
23 (render-ui main { type: data-list, entity: ?data, fields: [{ name: "title", label: "Title", variant: h4 }, { name: "body", label: "Note", variant: body }], emptyTitle: "No notes yet", emptyDescription: "Add one with the form.", emptyIcon: "file-text" })
24 NotesFailed -> ready
25 (emit MOVED { event: "NotesFailed" })
26 (render-ui main { type: alert, variant: error, message: ?error })
27 }
28
29 state ready {
30 RELOAD -> loading
31 (emit MOVED { event: "RELOAD" })
32 (fetch Note { emit: { success: NotesLoaded, failure: NotesFailed } })
33 }
34
35 emits {
36 NotesLoaded {
37 data : [Note]
38 }
39 NotesFailed {
40 error : string
41 }
42 MOVED -> external {
43 event : string!
44 }
45 @description "Each move names the event it took, so the diagram beside the demo can follow it."
46 }
47
48 listens {
49 NoteForm.NOTE_SAVED -> RELOAD
50 }
51 }
52
53 trait NoteForm -> Note [interaction, instance] {
54 initial: editing
55
56 state editing {
57 INIT -> editing
58 (render-ui main { type: form-section, fields: ["title", "body"], submitEvent: SAVE, mode: create, entity: {} })
59 SAVE -> editing
60 (emit MOVED { event: "SAVE" })
61 (persist create Note ?data)
62 (emit NOTE_SAVED)
63 (render-ui main { type: form-section, fields: ["title", "body"], submitEvent: SAVE, mode: create, entity: {} })
64 }
65
66 emits {
67 NOTE_SAVED
68 @description "A note was stored."
69 MOVED -> external {
70 event : string!
71 }
72 @description "Each move names the event it took, so the diagram beside the demo can follow it."
73 }
74
75 listens {
76 SAVE {
77 data : @entity!
78 }
79 }
80 }
81
82 page "/notes" -> NoteList, NoteForm
83}Kaj se zgodi, ko se sproži SAVE:
(persist "create" "Note" @payload.data)(emit "NOTE_SAVED")Kako se lastnosti pogovarjajo med seboj, po vrsti:
Vrstice se napolnijo enkrat, v prazno shrambo, in nikoli čez vrstice, ki jih obiskovalec že ima. Program, ki navede locales [en, ar, sl], lahko vsak jezik napolni posebej z instances ar [ … ] in instances sl [ … ]; glej lokalizacijo.
1(fetch Note { emit: { success: NotesLoaded, failure: NotesFailed } })
2(fetch Note { id: ?id })
3(fetch Note { filter: ["=", (object/get @entity status), "open"], limit: 20 })
4(persist create Note ?data)
5(persist update Note (object/merge ?row { done: true }))
6(persist delete Note ?id)fetch naloži vrstice in poroča prek dogodkov v emit; brez njih nalaganja nič ne opazi. Oba dogodka rezultata sta navedena v emits lastnosti. Znotraj filter je (object/get @entity field) vrstica, ki se preverja; golo @entity.field pa je okvir lastnosti same.
Če polju za tip določiš drugo entiteto, nastane relacija: customerId : Customer (ena) ali attendees : [Person] (več). (fetch Order { include: ["customerId"] }) jo napolni. T.f pomeni tip polja druge entitete, zato je tagId : Tag.id! niz, za katerega vemo, da hrani identifikator oznake.
Pravila dostopa so na vrhu telesa entitete in se uveljavijo enkrat, v podatkovni plasti, za vse lastnosti, vezane nanjo:
1entity Session [persistent: sessions] {
2 @read (or ["=", @user.role, "manager"] ["=", (object/get @entity trainerId), @user.id])
3 @update ["=", (object/get @entity trainerId), @user.id]
4 @delete none "sessions are archived, never deleted"
5 trainerId : Person
6 title : string!
7}@user je obiskovalec; @entity je zadevna vrstica. Brez pravila sme vsak izvesti to operacijo; none "reason" zabeleži namerno opustitev. Pravila varujejo podatke. Kaj zaslon pokaže ali skrije, je izrecno zapisano v programu, s pogoji.
Lastnosti so avtomati stanj, ki entitete berejo in spreminjajo.