diff --git a/shared/sx/ref/boundary-app.sx b/shared/sx/ref/boundary-app.sx index 213e1c0..e559e31 100644 --- a/shared/sx/ref/boundary-app.sx +++ b/shared/sx/ref/boundary-app.sx @@ -1,9 +1,12 @@ ;; ========================================================================== ;; boundary-app.sx — Deployment-specific boundary declarations ;; -;; Layout context I/O primitives for THIS deployment's service architecture. +;; I/O primitives specific to THIS deployment's architecture: +;; inter-service communication, framework bindings, domain concepts, +;; and layout context providers. +;; ;; These are NOT part of the SX language contract — a different deployment -;; would declare different layout contexts here. +;; would declare different primitives here. ;; ;; The core SX I/O contract lives in boundary.sx. ;; Per-service page helpers live in {service}/sx/boundary.sx. @@ -11,7 +14,92 @@ ;; -------------------------------------------------------------------------- -;; Layout context providers — deployment-specific I/O +;; Inter-service communication — microservice architecture +;; -------------------------------------------------------------------------- + +(define-io-primitive "frag" + :params (service frag-type &key) + :returns "string" + :async true + :doc "Fetch cross-service HTML fragment." + :context :request) + +(define-io-primitive "query" + :params (service query-name &key) + :returns "any" + :async true + :doc "Fetch data from another service via internal HTTP." + :context :request) + +(define-io-primitive "action" + :params (service action-name &key) + :returns "any" + :async true + :doc "Call an action on another service via internal HTTP." + :context :request) + +(define-io-primitive "service" + :params (service-or-method &rest args &key) + :returns "any" + :async true + :doc "Call a domain service method. Two-arg: (service svc method). One-arg: (service method) uses bound handler service." + :context :request) + + +;; -------------------------------------------------------------------------- +;; Framework bindings — Quart/Jinja2/HTMX specifics +;; -------------------------------------------------------------------------- + +(define-io-primitive "htmx-request?" + :params () + :returns "boolean" + :async true + :doc "True if current request has HX-Request header." + :context :request) + +(define-io-primitive "g" + :params (key) + :returns "any" + :async true + :doc "Read a value from the Quart request-local g object." + :context :request) + +(define-io-primitive "jinja-global" + :params (key &rest default) + :returns "any" + :async false + :doc "Read a Jinja environment global." + :context :request) + + +;; -------------------------------------------------------------------------- +;; Domain concepts — navigation, relations +;; -------------------------------------------------------------------------- + +(define-io-primitive "nav-tree" + :params () + :returns "list" + :async true + :doc "Navigation tree as list of node dicts." + :context :request) + +(define-io-primitive "get-children" + :params (&key parent-type parent-id) + :returns "list" + :async true + :doc "Fetch child entities for a parent." + :context :request) + +(define-io-primitive "relations-from" + :params (entity-type) + :returns "list" + :async false + :doc "List of RelationDef dicts for an entity type." + :context :config) + + +;; -------------------------------------------------------------------------- +;; Layout context providers — per-service header/page context ;; -------------------------------------------------------------------------- ;; Shared across all services (root layout) diff --git a/shared/sx/ref/boundary.sx b/shared/sx/ref/boundary.sx index 24f6e39..4bd0ecf 100644 --- a/shared/sx/ref/boundary.sx +++ b/shared/sx/ref/boundary.sx @@ -5,7 +5,7 @@ ;; This is the LANGUAGE contract — not deployment-specific. ;; ;; Pure primitives (Tier 1) are declared in primitives.sx. -;; Deployment-specific I/O (layout contexts) lives in boundary-app.sx. +;; Deployment-specific I/O lives in boundary-app.sx. ;; Per-service page helpers live in {service}/sx/boundary.sx. ;; ;; Format: @@ -28,38 +28,11 @@ ;; -------------------------------------------------------------------------- ;; Tier 2: Core I/O primitives — async, side-effectful, need host context +;; +;; These are generic web-platform I/O that any SX web host would provide, +;; regardless of deployment architecture. ;; -------------------------------------------------------------------------- -;; Cross-service communication - -(define-io-primitive "frag" - :params (service frag-type &key) - :returns "string" - :async true - :doc "Fetch cross-service HTML fragment." - :context :request) - -(define-io-primitive "query" - :params (service query-name &key) - :returns "any" - :async true - :doc "Fetch data from another service via internal HTTP." - :context :request) - -(define-io-primitive "action" - :params (service action-name &key) - :returns "any" - :async true - :doc "Call an action on another service via internal HTTP." - :context :request) - -(define-io-primitive "service" - :params (service-or-method &rest args &key) - :returns "any" - :async true - :doc "Call a domain service method. Two-arg: (service svc method). One-arg: (service method) uses bound handler service." - :context :request) - ;; Request context (define-io-primitive "current-user" @@ -69,13 +42,6 @@ :doc "Current authenticated user dict, or nil." :context :request) -(define-io-primitive "htmx-request?" - :params () - :returns "boolean" - :async true - :doc "True if current request has HX-Request header." - :context :request) - (define-io-primitive "request-arg" :params (name &rest default) :returns "any" @@ -97,13 +63,6 @@ :doc "Read a URL view argument from the current request." :context :request) -(define-io-primitive "g" - :params (key) - :returns "any" - :async true - :doc "Read a value from the Quart request-local g object." - :context :request) - (define-io-primitive "csrf-token" :params () :returns "string" @@ -134,22 +93,6 @@ :doc "Service URL prefix for dev/prod routing." :context :request) -;; Navigation and relations - -(define-io-primitive "nav-tree" - :params () - :returns "list" - :async true - :doc "Navigation tree as list of node dicts." - :context :request) - -(define-io-primitive "get-children" - :params (&key parent-type parent-id) - :returns "list" - :async true - :doc "Fetch child entities for a parent." - :context :request) - ;; Config and host context (sync — no await needed) (define-io-primitive "app-url" @@ -170,21 +113,7 @@ :params (key) :returns "any" :async false - :doc "Read a value from app-config.yaml." - :context :config) - -(define-io-primitive "jinja-global" - :params (key &rest default) - :returns "any" - :async false - :doc "Read a Jinja environment global." - :context :request) - -(define-io-primitive "relations-from" - :params (entity-type) - :returns "list" - :async false - :doc "List of RelationDef dicts for an entity type." + :doc "Read a value from host configuration." :context :config)