إنتقل إلى المحتوى الرئيسي

آلات حالة من الأعلى إلى الأسفل

· 2 دقائق قراءة
أسامة الغانمي
المؤسس المشارك والقائد التقني

في Orb، كل ميزة هي آلة حالة. ليست شجرة مكوّنات ولا مجموعة hooks — بل آلة حالة بحالات صريحة، وتحوّلات محميّة، ودائرة مغلقة يفرضها المترجم قبل توليد أي شيفرة.

الوحدة المدارية

الوحدة المدارية (orbital) هي الوحدة الأساسية: كيان (بيانات)، وسمة أو أكثر (سلوك)، وصفحات (مسارات). السمة هي آلة حالة. كل تفاعل من المستخدم يمر بدائرة مغلقة:

حدث ← حارس ← تحوّل ← تأثيرات ← استجابة واجهة ← حدث

هذا ليس توصية. المترجم يرفض البرامج التي تنكسر فيها الدائرة.

مثال كامل

orbital TaskOrbital {
entity Task [runtime] {
id : string
title : string
status : string
}

trait TaskBrowser -> Task [interaction] {
initial: browsing
state browsing {
INIT -> browsing
(fetch Task)
(render-ui main { type: "stack", direction: "vertical", gap: "lg", children: [{ type: "typography", content: "Tasks", variant: "h2" }, { type: "button", label: "New Task", event: "CREATE", variant: "primary" }, { type: "divider" }, { type: "data-list", entity: "Task", fields: ["title", "status"] }] })
CREATE -> creating
(render-ui modal { type: "stack", direction: "vertical", gap: "md", children: [{ type: "typography", content: "New Task", variant: "h3" }, { type: "input", label: "Title", placeholder: "Enter title" }, { type: "stack", direction: "horizontal", gap: "md", children: [{ type: "button", label: "Save", event: "SAVE", variant: "primary" }, { type: "button", label: "Cancel", event: "CANCEL", variant: "secondary" }] }] })
}
state creating {
SAVE -> browsing
(render-ui modal null)
(fetch Task)
(render-ui main { type: "stack", direction: "vertical", gap: "lg", children: [{ type: "typography", content: "Tasks", variant: "h2" }, { type: "divider" }, { type: "data-list", entity: "Task", fields: ["title", "status"] }] })
CANCEL -> browsing
(render-ui modal null)
(render-ui main { type: "stack", direction: "vertical", gap: "lg", children: [{ type: "typography", content: "Tasks", variant: "h2" }, { type: "divider" }, { type: "data-list", entity: "Task", fields: ["title", "status"] }] })
}
}

page "/tasks" -> TaskBrowser
}

حالتان. أربعة تحوّلات. كل نافذة تُفتح وتُغلق. كل حدث له معالج. نموذج البيانات، منطق العمل، بنية الواجهة، والتوجيه — كلها في ملف واحد.

الدائرة المغلقة

احذف تحوّل CANCEL وشغّل orb validate:

Error: CIRCUIT_NO_OVERLAY_EXIT
State 'creating' renders to 'modal' slot but has no exit transition.
Fix: Add a transition from 'creating' with event 'CANCEL' or 'CLOSE'

المترجم يُثبت أن الدائرة مكتملة في كل مسار. النافذة التي لا تُغلق ليست خطأ يُكتشف في الاختبار — بل برنامج لا يُترجم.

هذا هو الرهان التصميمي الأساسي: إذا كان سلوكك آلة حالة، يمكن للمترجم أن يستدل عليه. وإذا استطاع المترجم الاستدلال عليه، تصبح فئات كاملة من الأخطاء مستحيلة.