التوثيق

البدء السريع

اكتب برنامجًا وتحقق منه واختبره وشغّله، في خمس دقائق.

يبني هذا الشرح عدّادًا: مداريّ واحد بسمة واحدة. إنه صغير، لكنه برنامج Orb كامل، وكل خطوة فيه هي نفسها في البرامج الكبيرة.

1. اكتب البرنامج

أنشئ الملف counter.lolo:

lolo
1app counter "1.0.0" 2"A counter with increment, decrement and reset." 3orbital CounterOrbital { 4 entity Counter [runtime] { 5 id : string! 6 count : number = 0 7 } 8 9 trait Counting -> Counter [interaction, instance] { 10 initial: ready 11 12 state ready { 13 INIT -> ready 14 (render-ui main { type: stack, direction: horizontal, gap: md, align: center, children: [ 15 { type: button, label: "−", action: DECREMENT, variant: secondary, aria-label: "Decrease" }, 16 { type: typography, content: @entity.count, variant: h2 }, 17 { type: button, label: "+", action: INCREMENT, variant: primary, aria-label: "Increase" }, 18 { type: button, label: "Reset", action: RESET, variant: ghost } 19 ] }) 20 INCREMENT -> ready 21 (set @entity.count (+ @entity.count 1)) 22 DECREMENT -> ready 23 (set @entity.count (- @entity.count 1)) 24 RESET -> ready 25 (set @entity.count 0) 26 } 27 } 28 29 page "/counter" -> Counting 30}

اقرأه من أعلى إلى أسفل: الكيان Counter يحمل رقمًا واحدًا، والسمة Counting لها حالة واحدة هي ready. عند INIT (حين تُفتح الصفحة) ترسم صفًا من الأزرار والعدد. كل زر يرسل حدثًا، ولكل حدث انتقال يحدّث العدد. النص مرتبط بـ @entity.count، فيُعاد رسمه عندما يتغير العدد.

2. تحقّق

bash
1 orb validate counter.lolo

المعيار صفر أخطاء وصفر تحذيرات. جرّب كسره: احذف الانتقال RESET -> ready وتحقق مجددًا. يبلغ المترجم بأن زر Reset يرسل حدثًا لا تتعامل معه أي حالة. هذه هي الدائرة المغلقة: كل عنصر تفاعلي يجب أن يؤدي إلى مكان ما.

3. اختبر

bash
1 orb verify counter.lolo

يشغّل التحقق كل انتقال ويتأكد من أنه يفعل ما يعلنه: الحالة التي يصل إليها، والتأثيرات التي ينفذها، والشاشة التي يرسمها.

4. شغّله

bash
1 orb serve counter.lolo --open

يترجم orb serve البرنامج إلى تطبيق TypeScript ويقدّمه ببيئة تشغيل مدمجة، دون حاجة إلى Node.js. هذا البرنامج نفسه يعمل في هذه الصفحة:

آلة الحالات
Counting.lolololo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 trait Counting -> Counter [interaction, instance] { state ready { INIT -> ready (render-ui main <Stack align={center} direction={horizontal} gap={md}> <Button action={DECREMENT} aria-label={Decrease} label={"−"} variant={secondary} /> <Typography content={@entity.count} variant={h2} /> <Button action={INCREMENT} aria-label={Increase} label={"+"} variant={primary} /> <Button action={RESET} label={Reset} variant={ghost} /> </Stack>) INCREMENT -> ready (emit MOVED { event: INCREMENT }) (set @entity.count (+ @entity.count 1)) DECREMENT -> ready (emit MOVED { event: DECREMENT }) (set @entity.count (- @entity.count 1)) RESET -> ready (emit MOVED { event: RESET }) (set @entity.count 0) } emits { MOVED -> external { event : string! } @description "Each move names the event it took, so the diagram beside the demo can follow it." } }
INIT
INCREMENT
DECREMENT
RESET
nowready
يعمل الآن مباشرة

std-orb-docex-counter.lolololo
1app std-orb-docex-counter "1.0.0" 2"std-orb-docex-counter — the smallest complete orbital: one entity, one trait with one state, three buttons and a closed circuit." 3orbital CounterOrbital { 4 entity Counter [runtime] { 5 id : string! 6 count : number = 0 7 } 8 9 trait Counting -> Counter [interaction, instance] { 10 initial: ready 11 12 state ready { 13 INIT -> ready 14 (render-ui main { type: stack, direction: horizontal, gap: md, align: center, children: [ 15 { type: button, label: "−", action: DECREMENT, variant: secondary, aria-label: "Decrease" }, 16 { type: typography, content: @entity.count, variant: h2 }, 17 { type: button, label: "+", action: INCREMENT, variant: primary, aria-label: "Increase" }, 18 { type: button, label: "Reset", action: RESET, variant: ghost } 19 ] }) 20 INCREMENT -> ready 21 (emit MOVED { event: "INCREMENT" }) 22 (set @entity.count (+ @entity.count 1)) 23 DECREMENT -> ready 24 (emit MOVED { event: "DECREMENT" }) 25 (set @entity.count (- @entity.count 1)) 26 RESET -> ready 27 (emit MOVED { event: "RESET" }) 28 (set @entity.count 0) 29 } 30 31 emits { 32 MOVED -> external { 33 event : string! 34 } 35 @description "Each move names the event it took, so the diagram beside the demo can follow it." 36 } 37 } 38 39 page "/counter" -> Counting 40}

ما الذي يحدث عندما يقع الحدث INCREMENT:

readyINCREMENT
→
ready
Effects (1)What runs, in order, when the transition fires.
(set @entity.count (+ @entity.count 1))
@entity.count@entity.count1+set

5. ترجمه

bash
1 orb compile counter.lolo --output ./counter-app

يكتب هذا تطبيقًا كاملًا يمكنك نشره في أي مكان. البرنامج هو المصدر، ولا تُحرَّر الشيفرة المولَّدة يدويًا أبدًا.

Orb

لغة برمجة من آلات حالة قابلة للتركيب.

© 2026 المدار. ليوبليانا، سلوفينيا.
Not reported here