Explorar el Código

refactor(spry): introduce PathProvider and static resource system

Replace ComponentUriProvider with PathProvider and add support for
bundled static resources via spry-res attribute.

- Rename ComponentUriProvider to PathProvider for clearer semantics
- Add StaticResource infrastructure for serving bundled assets
- Add spry-res template attribute for static resource references
- Update component endpoint route to /_spry/com/{component-id}/{action}
- Remove unused StyleProvider interface

BREAKING CHANGE: Component endpoint routes changed from /_spry/ to /_spry/com/
Billy Barrow hace 1 semana
padre
commit
ab039c66c9

+ 1 - 1
examples/SimpleExample.vala

@@ -42,7 +42,7 @@ class ContentComponent : Component {
 
 class MessageFormComponent : Component {
 
-    private ComponentUriProvider component_uri_provider = inject<ComponentUriProvider>();
+    private PathProvider component_uri_provider = inject<PathProvider>();
 
     public override string markup { get {
         return """

+ 1 - 1
examples/TemplateExample.vala

@@ -333,7 +333,7 @@ class MainLayoutTemplate : PageTemplate {
             <meta name="viewport" content="width=device-width, initial-scale=1.0">
             <title>Spry Template Example</title>
             <link rel="stylesheet" href="/styles/main.css">
-            <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>
+            <script spry-res="htmx.js"></script>
         </head>
         <body>
             <header>

+ 13 - 2
src/Component.vala

@@ -21,7 +21,7 @@ namespace Spry {
             // No-op default
         }
         
-        private ComponentUriProvider _uri_provider = inject<ComponentUriProvider>();
+        private PathProvider _path_provider = inject<PathProvider>();
         private Catalogue<string, Renderable> _children = new Catalogue<string, Renderable>();
         private HashSet<Component> _global_sources = new HashSet<Component>();
         private MarkupDocument _instance;
@@ -136,7 +136,7 @@ namespace Spry {
                 var component_action = action[1];
 
                 node.remove_attribute("spry-action");
-                node.set_attribute("hx-get", _uri_provider.get_action_uri(component_name, component_action));
+                node.set_attribute("hx-get", _path_provider.get_action_path(component_name, component_action));
             }
 
             var target_nodes = final_instance.select("//*[@spry-target]");
@@ -156,6 +156,15 @@ namespace Spry {
                 node.set_attribute("hx-swap-oob", @"[spry-global=\"$key\"]");
             }
 
+            var script_nodes = final_instance.select("//script[@spry-res]");
+            foreach(var node in script_nodes) {
+                var res = StaticResource.from_identifier(node.get_attribute("spry-res"))?.get_path();
+                if(res != null) {
+                    node.set_attribute("src", res);
+                }
+                node.remove_attribute("spry-res");
+            }
+
             // Remove all internal SIDs
             final_instance.select("//*[@sid]")
                 .iterate(n => n.remove_attribute("sid"));
@@ -184,6 +193,8 @@ namespace Spry {
             }
         }
 
+
+
     }
 
 }

+ 1 - 41
src/ComponentEndpoint.vala

@@ -6,49 +6,9 @@ using Astralis;
 
 namespace Spry {
 
-    public class ComponentUriProvider : Object {
-
-        private Dictionary<string, Type> type_mapping = new Dictionary<string, Type>();
-        private Dictionary<string, string> name_mapping = new Dictionary<string, string>();
-        private Container container = inject<Container>();
-
-        public Component? get_component_instance(string id, Scope scope) throws Error {
-            Type type;
-            if(type_mapping.try_get(id, out type)) {
-                return (Component)scope.resolve_type(type);
-            }
-            return null;
-        }
-
-        public string get_action_uri(string type_name, string action_name) throws Error {
-            var component_id = upsert(type_name);
-            return @"/_spry/$(component_id)/$action_name";
-        }
-
-        private string upsert(string type_name) throws Error {
-            if(name_mapping.has(type_name)) {
-                return name_mapping[type_name];
-            }
-
-            var registration = container.get_all_registrations()
-                .where(r => r.implementation_type.is_a(typeof(Component)))
-                .first_or_default(r => r.implementation_type.name() == type_name);
-
-            if(registration == null) {
-                throw new ContainerError.NOT_REGISTERED(@"Could not find registered component with name $(type_name)");
-            }
-
-            var uuid = Uuid.string_random();
-            type_mapping[uuid] = registration.implementation_type;
-            name_mapping[type_name] = uuid;
-            return uuid;
-        }
-
-    }
-
     public class ComponentEndpoint : Object, Endpoint {
 
-        private ComponentUriProvider component_uri_provider = inject<ComponentUriProvider>();
+        private PathProvider component_uri_provider = inject<PathProvider>();
         private Scope scope = inject<Scope>();
 
         public async Astralis.HttpResult handle_request (HttpContext http_context, RouteContext route_context) throws Error {

+ 44 - 0
src/PathProvider.vala

@@ -0,0 +1,44 @@
+using Invercargill.DataStructures;
+using Inversion;
+
+namespace Spry {
+    public class PathProvider : Object {
+
+        private Dictionary<string, Type> type_mapping = new Dictionary<string, Type>();
+        private Dictionary<string, string> name_mapping = new Dictionary<string, string>();
+        private Container container = inject<Container>();
+
+        public Component? get_component_instance(string id, Scope scope) throws Error {
+            Type type;
+            if(type_mapping.try_get(id, out type)) {
+                return (Component)scope.resolve_type(type);
+            }
+            return null;
+        }
+
+        public string get_action_path(string type_name, string action_name) throws Error {
+            var component_id = upsert(type_name);
+            return @"/_spry/com/$(component_id)/$action_name";
+        }
+
+        private string upsert(string type_name) throws Error {
+            if(name_mapping.has(type_name)) {
+                return name_mapping[type_name];
+            }
+
+            var registration = container.get_all_registrations()
+                .where(r => r.implementation_type.is_a(typeof(Component)))
+                .first_or_default(r => r.implementation_type.name() == type_name);
+
+            if(registration == null) {
+                throw new ContainerError.NOT_REGISTERED(@"Could not find registered component with name $(type_name)");
+            }
+
+            var uuid = Uuid.string_random();
+            type_mapping[uuid] = registration.implementation_type;
+            name_mapping[type_name] = uuid;
+            return uuid;
+        }
+
+    }
+}

+ 4 - 2
src/Spry.vala

@@ -5,11 +5,13 @@ namespace Spry {
 
     public class SpryModule : Object, Module {
         public void register_components (Container container) throws Error {
-            container.register_singleton<ComponentUriProvider>();
+            container.register_singleton<PathProvider>();
             container.register_scoped<ComponentFactory>();
             container.register_scoped<ComponentEndpoint>()
                 .as<Endpoint>()
-                .with_metadata<EndpointRoute>(new EndpointRoute("/_spry/{component-id}/{action}"));
+                .with_metadata<EndpointRoute>(new EndpointRoute("/_spry/com/{component-id}/{action}"));
+            
+            add_static_resources(container);
         }
 
     }

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 7 - 0
src/Static/Htmx.vala


+ 52 - 0
src/Static/StaticResource.vala

@@ -0,0 +1,52 @@
+using Inversion;
+using Astralis;
+
+namespace Spry {
+
+    public enum StaticResource {
+
+        HTMX;
+
+        public static StaticResource? from_identifier(string identifier) {
+            switch(identifier) {
+                case Static.HTMX_NAME:
+                    return HTMX;
+            }
+            return null;
+        }
+
+        public string get_identifier() {
+            switch(this) {
+                case HTMX:
+                    return Static.HTMX_NAME;
+            }
+            assert_not_reached();
+        }
+
+        public string get_content_type() {
+            switch(this) {
+                case HTMX:
+                    return "text/javascript";
+            }
+            assert_not_reached();
+        }
+
+        public string get_path() {
+            return "/_spry/res/" + get_identifier();
+        }
+    }
+
+
+    internal void add_static_resources(Container container) throws Error {
+        add_static_resource_string(container, StaticResource.HTMX, Static.HTMX_DATA);
+    }
+
+    internal void add_static_resource_string(Container container, StaticResource resource, string data) throws Error {
+        container.register_startup<FastResource>(() => 
+                new FastResource.from_string(data)
+                    .with_content_type(resource.get_content_type())
+                    .with_default_compressors())
+            .as<Endpoint>()
+            .with_metadata<EndpointRoute>(new EndpointRoute(resource.get_path()));
+    }
+}

+ 0 - 28
src/StyleProvider.vala

@@ -1,28 +0,0 @@
-using Invercargill;
-namespace Spry {
-
-    public interface StyleProvider : Object {
-
-        public abstract string? get_css();
-
-    }
-
-    public interface CssClassProvider : Object {
-
-        public abstract string fg_primary { get; }
-        public abstract string fg_secondary { get; }
-        public abstract string fg_tertiary { get; }
-        public abstract string fg_success { get; }
-        public abstract string fg_caution { get; }
-        public abstract string fg_danger { get; }
-
-        public abstract string bg_primary { get; }
-        public abstract string bg_secondary { get; }
-        public abstract string bg_tertiary { get; }
-        public abstract string bg_success { get; }
-        public abstract string bg_caution { get; }
-        public abstract string bg_danger { get; }
-
-    }
-
-}

+ 3 - 1
src/meson.build

@@ -7,7 +7,9 @@ sources = files(
     'Renderable.vala',
     'ComponentEndpoint.vala',
     'Context.vala',
-    'StyleProvider.vala',
+    'PathProvider.vala',
+    'Static/StaticResource.vala',
+    'Static/Htmx.vala'
 )
 
 

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio