1 module spasm.spa; 2 3 version (LDC) 4 import ldc.attributes; 5 public import spasm.types; 6 public import spasm.dom; 7 public import spasm.node; 8 public import spasm.event; 9 public import spasm.array; 10 public import spasm.css; 11 12 nothrow: 13 14 extern(C) { 15 Handle getRoot(); 16 } 17 18 version (unittest) { 19 auto assumeNoThrow(T)(lazy T block) { 20 try { 21 return block(); 22 } catch (Exception e) { 23 assert(false, e.msg); 24 } 25 } 26 auto renderToNode(T)(auto ref T t) { 27 import unit_threaded; 28 Handle rootIdx = cast(Handle)unittest_dom_nodes.data.length; 29 auto rootNode = new UnittestDomNode(NodeType.root, rootIdx + 1); 30 unittest_dom_nodes.put(rootNode); 31 t.setPointers(); 32 spasm.dom.render(JsHandle(rootIdx + 1), t); 33 // assert(t.getNamedNode().node != invalidHandle); 34 // assert(t.getNamedNode().mounted == true); 35 return rootNode; 36 } 37 string renderToString(T)(auto ref T t) { 38 import std.format : format; 39 static if (is(T : UnittestDomNode)) { 40 auto node = t; 41 } else 42 auto node = t.renderToNode; 43 return format("%s", node).assumeNoThrow; 44 } 45 string renderToString(T)() { 46 T t; 47 return t.renderToString(); 48 } 49 } 50 51 void addApplicationCss(Application, Theme)() { 52 enum css = GetCss!(Application, Theme); 53 static if (css.length > 0) 54 addCss(css); 55 } 56 57 mixin template Spa(Application) { 58 struct Empty{} 59 mixin Spa!(Application,Empty); 60 } 61 62 mixin template Spa(Application, Theme) { 63 import spasm.rt.gc; 64 __gshared Application application; 65 pragma(mangle, "_start") 66 extern(C) 67 export 68 @trusted void _start(uint heap_base) { 69 import spasm.rt.memory; 70 alloc_init(heap_base); 71 addRoot(&application); 72 auto root = getRoot(); 73 addApplicationCss!(Application, Theme)(); 74 application.setPointers(); 75 spasm.dom.render(root, application); 76 } 77 version(hmr) { 78 pragma(msg, "spasm with HMR"); 79 import spasm.hmr; 80 pragma(mangle, "dumpApp") 81 extern(C) export string dumpApp() { 82 return application.dumpState(); 83 } 84 pragma(mangle, "loadApp") 85 extern(C) export void loadApp(string state) { 86 application.loadState(state); 87 } 88 } 89 } 90 91 struct Parameters(Ps...) { 92 static template opDispatch(string name) { 93 alias opDispatch(alias P) = Parameters!(Ps, Param!(name, P)); 94 } 95 } 96 97 auto param() { 98 return Parameters!()(); 99 } 100 101 struct Param(string name, alias field) { 102 alias Name = name; 103 alias Field = field; 104 }