From 1648a4f875b773a100855eb7547146559fd2745d Mon Sep 17 00:00:00 2001 From: Antonette Caldwell <18711313+acald-creator@users.noreply.github.com> Date: Mon, 13 Apr 2026 02:18:25 -0500 Subject: [PATCH 1/2] feat: add Relay data fetching with mock GraphQL server Add rescript-relay with a bundled graphql-yoga mock server serving User and Post types. PostsPage fetches data via a Relay query with Suspense loading. App wraps in RelayEnvironmentProvider. Includes relay.config.js and generated Relay artifacts. Closes #35 --- biome.json | 4 +- bun.lockb | Bin 363672 -> 382636 bytes mock-server/index.js | 94 +++++++ mock-server/schema.graphql | 28 ++ package.json | 121 +++++---- relay.config.js | 6 + rescript.json | 3 +- src/App.res | 36 +-- src/__generated__/PostsPageQuery_graphql.res | 252 ++++++++++++++++++ .../RelaySchemaAssets_graphql.res | 31 +++ src/pages/PostsPage.res | 72 ++++- src/relay/RelayEnv.res | 35 +++ 12 files changed, 604 insertions(+), 78 deletions(-) create mode 100644 mock-server/index.js create mode 100644 mock-server/schema.graphql create mode 100644 relay.config.js create mode 100644 src/__generated__/PostsPageQuery_graphql.res create mode 100644 src/__generated__/RelaySchemaAssets_graphql.res create mode 100644 src/relay/RelayEnv.res diff --git a/biome.json b/biome.json index 17a9d15..20b4762 100644 --- a/biome.json +++ b/biome.json @@ -6,10 +6,10 @@ "rules": { "recommended": true }, - "includes": ["**", "!**/dist", "!**/*.bs.js", "!**/lib"] + "includes": ["**", "!**/dist", "!**/*.bs.js", "!**/lib", "!**/__generated__"] }, "formatter": { "enabled": true, - "includes": ["**", "!**/dist", "!**/*.bs.js", "!**/lib"] + "includes": ["**", "!**/dist", "!**/*.bs.js", "!**/lib", "!**/__generated__"] } } diff --git a/bun.lockb b/bun.lockb index c0ffb41a46db2721c2fde874011b70d56ba4bdfe..b339a3caa8e7522bb17782f93c83a108f627b223 100755 GIT binary patch delta 82907 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 IIv>jA}P>3YC6fkOh9nzTCrxwit= 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 JbL%ader;@Q zS=+)cT3LK#80506sH(I^Te}*Lrd3bX%{t7kHsKHG#Z6pBdeG8{BRSthydMy4oQld z7?Pi%eYYH`a%tu7(hD#}H;B)x_KSv-2dhIgqHk1baH>|Wo1&r5@A*8`i#N`}_M(WT zwj*A*PSJJL5E~jYdTC654;A{B)GB+ZnQuwGp@(Yw4x1f`A-ytw#Sh+#zWuO*82&weGQUfwf93q`ca>6kFKn=|Fw&u!3gYEM8%5r zv2;$+c+z2Dlgu4$@6n)X#Ku?C)mBJYcV|Fa4I9>^e(nKrrI;~{fonC!+h;$c|M5pE z+YC3xl(j_()ii-{!*8$Xr8mOC$dDVo{@NX;mE2pVK7Iahv(|T47ZaSTeV!G@6GP^? zkv|XUcewO5)v?-g8B?yCxKUP{TVxIfk#w(*{o1ZLm-~-b zR;LOqt$gW7MUY5EL?!Ia;k|NvcB_+Fc@>e!N@DHHTR(T+kmb7Vv!o>w8OlGcKU{6a znhOaI$xtNB1W|QX4nH>Y*6xFbB$A-{Mx;gYdtIkb{KXU@*@=V+KkA<{d55Ry<-OHm z?gElRNaAaJns##6uazB=_ek;~c^$Ffb-EfGYdR!$?zb|_KFroIf2KoK3y6gDr8|^G z!~l;-iMOiA3$ zXh;=}oV54Wt)JfvacG=E!V)LyNXla4(nXyry^=v`{sz#pUw{IbE=C&BNU0;^TNAadNAqM^>YqM{~&c;;^wQam%Cz^bh-h4$pv4dyIZyoQQNMaz||p$<#T zu$t-ve*4zi`g&%`!I>*QJQ^gcO<8BrHxAZT-l@@uMMGAq3nL4rzqVszCNxU3lc5D~ z)K)?1vH7I78i}U$U2QclHMSSHN2js5savU;81(CaLUr}|U{TLWkIueo{{$nl9b?iB zL?Y&omAc~9>P*UkNaR-G<725+SA}3Fpg9_HkKC~9uP#o1oEopimD$A71&Q2_%Wp53 z-*b}nkSX!8463UZ64yS#NVm*om2T?lx)mH6^XsZuvA))@-s6Y1%R>%b@IgaXbadNY zh9t+9_c1MpRh8wfk!QV7|8w10QwOVvwA74QQ~zVcq!H!@tK*X?$D&}pnI`AEd9HSg zeE*Oa*%Z(fjLNsKLn9q^vA1E@L)L_|GmUbfVKhPMZ}p09b+SR+?T5q5qQJ^l?#XkI zNbkM5vH$VsQ@V_BNQ^#^OgXHk_`fdR*CQlj=YJVow!VtX@I{@g;u&qZ>?`W)tHvW6 zEAHypxIF7?sxeUNz-XDbD9Cj6Hbeex*@Bj`0k}_y3n5?6`v1NUtZk?-dAD_cUG;U} zSLMixEKj{Tux+S9vNJKJY@`-ury#8wsqNWqQ2`$s>s#ES-^a}SVQ9oK*|KrEWZ`7B ziQe{Uy<8(})owIgB&D^@92>!i9JWsOz^3|0+1Pd6`Qusla@RG7d5xy(aSl>x)>JK= z!l?CdW7KwNs>-|3?L3<4hT}W7Y;vvqe%V!*)-zeGnd*&(wMsJ;l+%_iFVn$9lx0cY z(rMw98n2i1Mp+ieNU*&(k#Y)xLR+ZE1&PmIHhoS#`K995?YVtz=PL6OF~8ioj+Ct{ z_h)QP7hBbH>{y+X)x6a+vs#~vfI_WQNC8~0Rw_>XZsZ8$yX(Vsc} ztxj^@KpK`dt&}$!szz>GDeIY5YItsK+V?wXogI?7;_reiWo zKq8%`{vYM%u6p)8_koH5y2ZMoYNiL%P3KVkez52_&mW6UI?ld3%qLJg7>Yz9qtG(# z)uA7&yuYYRZG0Yuc9Fxyyx38Z@%r;Ft?@=Aid}w5}81TUvT;9l0s3%i;W9!Z*_W394W77n4WIV3TdqYsfNgjoi{y@xK)veM)jK&e%rI~ z?_Efwu9#jMg{j4PXoL=iM)P5>Z)c6%u*c9KZoe>fhIFlC!ckntO@{=e?CZY+3XBO8P8d^&9_? zf3{t`Qfbdfs}pVLRR&2@A5}3g29sa>8V2PsX=+}ZuWs0tb4&h>a#caoCA+RFBTb%L zx$4=9xw<<(U%%qHw2IY6x|SWj1giH9tI^K(ubwJt5q5V}E;A^(-Xd=HV;%L|LeJvo za(Djjo$O_dNhD9WDxQx_=r(=rZ9C}`K+eOn(p($2X&stIU+>jP#Ypcmc7`f0pDo0y z_kZ7{BgPz2YEypOLUUOC%P<<;O^q&K^Rn1@8(gdm&FS6L zg91!?+|EiDB;TwhBE)6tNIWm7GXsznJy!u6h@uyI1b6SJ1jC%f^q+@VcX; zg6bimVWRr1x@H;pO-|!zO1f-^?rJY_&8bK|EoAFrPhLH=hwAT1PS*vi)tHO8@kt5&zZHG`siM2Ha4tTGOORkT~S}X6Zckc zQ9h-Z6Sx%>n9U z5o|UbpzKA7VYv31#E?0qbe*G*eHY{!Y||H4ocJsosOlFbhJBD4iyQFGAiak??D6Y@ z=64%NzKv4{A0%Sq&umwZ2lxKe$Vio0dgve(Pipq@XkJRliE9Y-MUfK+=ur4!ut(84vF6K>{%If4#5y*yx-Pv_c&F#z3kdtJW z#pC829d#yylu`=gE64oWxjHA@#l6ssK{GR&w(Vzfhgy1jqG>Dx_Ki?&z36etFBG_g z$9PfdCQ<4Gwyd3^RQ8gzMiRe@F3Do<%S>wtk?U=v)bWx;H@246eWRki88!RJSvGPu z>HUMgT~4&FL(b&Lko$JVF?#8ClyF{|>C_=<2jjk(dyEQ^xSi3E8j482d%(t8u}9G` z`hGE9dYAsW^{xBmnNf>>M#73xMqI#HwUD^>a5SVwh8-`xb==Fxf9e`icLT?&Sg}3{ z4cR4T>+Ev9e$hHROdH;oWk@7lb?f%P%U7pNwK|n%K_M-(Zme?mA?|L&`qI!zIbIAd zwa}sQ)pdfl>2evTB7CUVWnW$O;UDqQgQuaR6c9X+;yK(9c(rui| z?`w;)x{p^s_%eUo8n68VEULwr!S0pbZzv(Qw4r24Jwc`S!&b=&+AG^p@Ar=F*~IlK zCl97Z>j^3djesd=6r?`hjBc7`$Avvx92y%9iTlnG{XQ%TSm}_QouHnhWq0Vny6gl%yGg*)wT)l>WM0%Iqn}5RT$y+ z^H`Kok*R8pE14=hlIJV5y^Nfj6V>8CH2;~X){6zYE8i1zv+Adq)vT6D%F~|%z@#aK zPga{G#4}|=Dm|u0^0wQ4-Zsm`z0n+VWUUvq{Ttld$SQD?dgRpi-U*d+O<348@d9i z{rsyK8av#6yBZsta0`jHFY&X~o2jOjVN5aU>@V|`^j(~G5m#pWFOO)gW(WLVy7oEI zdd8j8T$?!j(^-~xOfT9r!I`p47pin=v?^YXsny7ys#ea%7HO~*?Fo?c}i1lo*Id3e?3pX$4)rX{6m2P<)0hn_Ga@rKe__NEsKIoRG%)CY-GJR zzak1U?K8RR3Rc6xaH$I1HvczMj{gF+P||9!Ku^p4u4lhpn`hNCGQ$?on9z)#?y3?h z*xapE7pgcJduGpQy-=TRUkA^4;&ZEjeqW~l`CA4oR1pQ!=KBYvlfTcWZ~Hk*d8X8hNqR{q^=z6`xg+b)aU;-(uP_ z^Jn@E+g5$NWViWS^x448x@)o8E2-XDEH9H?>g`X%aQYsy-9iAo>j z7)h#P5RI!RkZ2egN&Gj4zl>|n0mhL0JUN=hF$c3*EHgZ*-)xrY%k`@4+c^HsgpUDD z9EJLMx$>&QfXjiXnQ<0)TmTQtrgF;g=uHEAw%+fvC% zH2-CqGHlqB??_T7GEbT|lcbvL^yTYq-fGMkM(tQbR;v2dsDlM7d83LtxVdxKu9xjs zxtb;Q@&AB?wPn=KqTl6t^7CA76PE}nKuC#IYO%y^xJrM#F}KHnlR4)18LGwQ4J9AH zK}fzqGi}ipp_xyVke47hq-VynEMBGJiEBNuN?mP<`*4-=sE)17Kk8kuTj~m3S3F43 z&CG|tB@l@RwjS4SHvL}a2wAXWi??4a&3;rpCGKD}B&QoDEx5A3QJSL z-HkD}LH8XR>(;87V*NB4GFfzaykJb_F(r7>Nw?wS^BM_{8l&#M{ZJ)WrwT1iiND2j zow_b@8?DnHZnaO9VSc#kU((d@@$Z8~%KP2wTuXO)-w!1J!m{ejs=X;1tF21JN`=G(ZZR}mvu;(qGKd( z2Q;KsM+KG$3iI6*U~2gIOflkaOz5AzY38o!O^LrHX1)3#IlGC5Oz#K&c3&D(ci4G{ zhHZoLu8sA;4cb=`qNW|o`16(&*AAN+K0a-c6eaG4>wKB54et?~wdp^3gBnR(dkh*p z?Ts2brF@G{gHo6Ntl@JN>mBHkDPmL%%Srn;F?x@TdER2q)rvnRs{fFf=sIL03WXw= zI{SO1W$@l?cTH3NmNiJEf=d5hvtg~Z$J&_^AMfKaDn#NwL!&qvPkuT6caJXZKi|Xr zE$$ojM)hwuV_f?S3*F4P{+99^)k5Oh+oB=q?j6!;>z1`uFFG_PZB(&hJq8UKhIyK7 z-?6*ykwK=0kN0^bUP$5si%qVxqr+rV;%{-@q}=Ngx9}#t3InJY}K?$U}g2<=axDy;HM^U=t@3m1WT;wG{LAU1;P( zV@8^q->O$H3{iGwwV>cklM2;e=M_u0R zTZcn?+Dbb(-m^`4)g$g7Xh>`32_4n&re&bK%_s|QZw{=HNEfVG@yKu1BbzI05^Zn% zWV;$pTx+f!D!LvyGV)>ldKui34L9$>$=t=wwm17zvVL~u;TNNut1O`21)O{y(Yd&Gh%H}8pwaF=c^3euvOH||8?$*Jng+eE9iWLHvUER0ZX({AMSUsevrd~DXU)K+pC zFqR>SRm-<tl&1tP~ED95cC#`&au1&lVN+w&0jcCTrRcoS5VcapI z{yeVz7%pmNhwbg>>?kCU!;BS3(iF@Uy%}z8?u#9zw za~Vfv8&zo!!JMqC&*hj~$i8xIF4J5Yi?QEI+#8d2X|p}dHm7gQY{!D*tG8$$*`zq~ zn52$n&iSuKnwb{*G3^u8Q=)LKznW9Hv0VMiYDQXHPA31e6jFcx8RBLwaYY?x$=j{c z6@J`BWgRYjeD0Bh3l6zD`FaiJ6q}#^AjyDa)hw3-qb2||4YahlgFl=+ z5dN;-Mk<)oYq{M;BGELSX8i4Knz_T}g$J_4o^twC71EJ=g=5(O~qovn&G-~564#WnubO|kL&u1+U4l> zei;TW%I2^&1&N&g{CNM{@v~C3`O_gWttTHhXPjC}`T>4%dcSpvTeh#&(3QNyXO=bu zi5=@@@}4+2FY-j7L((lyJ(jo=&~Qg%Wclo_QxZmZc4(|LBv%Jq{U_7djlVb~hvHQE zPL%s58j|;1^QNBRM{+qG8csJ})G)-FRD#?`)eWuhz;jXh4ZO`WbAGP3;D>_~W@89m?xwEGNf=>AfxA z9@o3|?o^WBau^REj3d*40OF=6$AhQz|0QeuyJ=|1Qk0FwSAL0MJU=2o>$})|U0>YQ ztq-4dpk=E49*e9_ckZfZU2J8oXYVPmuH^W}JyokK&yP#qSDVCN`Mx^Zm3J#w-`8Vq zz3(3Ubnun~T0Jo%_*jyEX1e*l3hqWd?ImtzavVSQ?Avr1gSP8&SuOPWjk*hQn6e165yAEAUX?<9z=l>d@l8yLpNe#@LmArY*w_h{IMo zY`v;oc6F5#<#_&8-q36tujhEpmMlLXIF-MXBbATwDxOs2eHkrZNnCrn$NG%(L0tb~2#z6TP>rI5uy{l5S_1Md%Z}1n6z)ZAj95nzf{D z{~Jz7q%R;D@pQwyIi5r84%$gg$i|suY(QN}7^7e{ffMvHKnUFj6+vDT% z$%!;JCGO!TDwMePQ}hbid+s~5y4B&$m#=H-(vrSD7oMn@V*NHYvY^pC`b|@(Tqo)q z=`-^N8g2V?vHqjeZ}iaL0r2r>=)HcTu1nm?SkFe>kEvQsNtLUs{ydx?pivu7^?Sg! z2DkD>gul|CV`;zg@OY|<_xhJU=Ic}bscPGct(@7Gbsne~{PyJAVdy{V12*%F{YS6M z($&M4w|CAVJ8gdBA@woiAB*zoZOdV$QtR}#`8r=AAhNg3C(k1z&e=k>JIATN`)F~r zcQ@Xkazf&??WFGXwngP>^Fl9F!%D{|t;~ANu2mI3)bq9scwtfd`q^?gkLO}hADfSJ zG#97)*dm>yU(&>V5v}E-M_*fbo~f_&F>~rr-JqfiW76toWNt~SnbmdH>{>#x- z^Ora|Sku+sEBKt`&#x@1SwCA{Gl3k=hN!NUk)OUl^^(jRL4Lfz^v0qp_a}F;T(s&> z#_PPbs2PNOu72~$dWt6MD#pxkm2rSA#CgR#KAAPrmct(NPOtiJ=kE>tJMGjMZJO3z zHluN753of!uXt}!*#_E*IRC^&<$<=md4^K;GHm#(b}H;xyBEaaK*r0jlx5{diyASI zG8IX%sAB`kmOmGt21>S4E4M+mYK7tx^ik3IlWydvxszhO-G>#C8q(*NKA$XV)SyHq zF*=kwK8Uw`R$H93akqH5a#wHq`L?PS#ag$Ku1dY9<tD|5I;w#WQI#obY`xSy%a57Q=_VscYR2*giA+H026m1-|5pNM$0JEa-sqP8 zP+~Y;CncY*a6x6ko?<&H4*7`#U<#`JRxGtL#(woon{f__ zk&68rG^8KIZ>+G)bz76dnua`WwHWDJja2Oa7q*-;sNrKMQ?3k7+AYj&$*}p;RyX!F z@Q^({x)Tvd5*Y- zhRQXLPGoqjW+u%7f3=#m9%05XoBNXse`Jw_hP}8@CURZx=GvY_>pHAm;>S_&+*wr0 z@jRq2l0_edSvLCaT6L_rtchSgQ?2vAUcW%8Kk?GfWy7F&t4%%$K(*Pw^7_2IzEA3A#hNc*8x^efOk+f{gpjw( zb0>WhPToJKiutF%cdp#0+fv%Exa+;?`}(J!wLBRuD?Rx}h)hiX`QkV)l~0>)%lR)Q zH1ppluev&&{Ey13-xAk7f4$uM{1bU3Eyd>b#0t12_dw;o-4M_lVYb*DDo$f56`NQ$ppAdy?im{Bc)ia&ZN zlYJ?A8l^Kb8_=MDllB0$$IiMp?)ASQbBcUCg}ASg$b4}7*zmcH+x>JEi80!%7F5G$ zvKJ04q>qGZFEVXgcVwTO;2BL>8;J{XU!7@NVEQCJ()L+mj1hYaL*uWPtMjJG=(fwD zVdPBJnZnyhAxjdD9HkC8e(@EO~uRrl^uG^O^=Hi>|(_ zNEl_SP*{0L*Eh0cPkug_R#^2!)4mj2GWS+U+a~VL`fd}zYa zqU8=IjFy)JO8>`zvnSswh7DDI?&r?rn0k&ERa57Zm7Dx(L|$z@9k8X!zLU?wY#jWt z=A=WsE2{RR5s!~jNjSZDmF($ z>U!7r;chkOc01(I=!Zm}6E~R=G&-ivO@5YZraQ4E=al?g-CA}0&Q>i;`+glXzpX)R z^*;T#9^mg8zx&SS-d?^|D3fNFd3&my%JJ>h>GdK%tl;;5te#a^C}PV)jL+sj^ZQbVI{6|H`? z)vjopdw%bRy8h%pN{`#!#Q#!t{Gy-f(!2@pqmTX4xS@K7p7n>uDwopTvf`d@sahKD zP;sxcRNpJz?q&Rum0Ih&uys(bY^F={lZIx_Z+BP@}zKA?M0=+65AY6$*E#~u;o|oi*0Gu^p&=c>3g;B7T%$M ziFW<^b?vO$p!S-i5{r*AJRMA@DAu3vE$iZ+jaMJ9mD%e5)ob7cTjz9 t*j#tqx@N1ALdE`ItH_tBYylZ|+bW* diff --git a/mock-server/index.js b/mock-server/index.js new file mode 100644 index 0000000..2ca1c0c --- /dev/null +++ b/mock-server/index.js @@ -0,0 +1,94 @@ +import { createSchema, createYoga } from "graphql-yoga"; +import { createServer } from "node:http"; +import { readFileSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const typeDefs = readFileSync(join(__dirname, "schema.graphql"), "utf-8"); + +const users = [ + { + id: "user-1", + name: "Alice Chen", + email: "alice@example.com", + avatarUrl: null, + }, + { + id: "user-2", + name: "Bob Martinez", + email: "bob@example.com", + avatarUrl: null, + }, +]; + +let posts = [ + { + id: "post-1", + title: "Getting Started with ReScript", + body: "ReScript is a robustly typed language that compiles to efficient and human-readable JavaScript. It comes with a lightning fast compiler toolchain that scales to any codebase size.", + createdAt: "2026-04-10T10:00:00Z", + authorId: "user-1", + }, + { + id: "post-2", + title: "Building with Rspack", + body: "Rspack is a high performance JavaScript bundler written in Rust. It offers strong compatibility with the webpack ecosystem while providing significantly better build performance.", + createdAt: "2026-04-11T14:30:00Z", + authorId: "user-2", + }, + { + id: "post-3", + title: "Emotion CSS-in-JS Patterns", + body: "Emotion is a performant and flexible CSS-in-JS library. It allows you to style applications with string or object styles and has a predictable composition model.", + createdAt: "2026-04-12T09:15:00Z", + authorId: "user-1", + }, +]; + +let nextPostId = 4; + +const resolvers = { + Query: { + posts: () => posts, + post: (_, { id }) => posts.find((p) => p.id === id) || null, + me: () => users[0], + }, + Mutation: { + createPost: (_, { title, body }) => { + const post = { + id: `post-${nextPostId++}`, + title, + body, + createdAt: new Date().toISOString(), + authorId: "user-1", + }; + posts.unshift(post); + return post; + }, + }, + Post: { + author: (post) => users.find((u) => u.id === post.authorId), + }, + Node: { + __resolveType: (obj) => { + if (obj.email) return "User"; + if (obj.title) return "Post"; + return null; + }, + }, +}; + +const yoga = createYoga({ + schema: createSchema({ typeDefs, resolvers }), + cors: { + origin: "http://localhost:8080", + credentials: true, + }, +}); + +const server = createServer(yoga); + +server.listen(4000, () => { + console.log("GraphQL server running at http://localhost:4000/graphql"); +}); diff --git a/mock-server/schema.graphql b/mock-server/schema.graphql new file mode 100644 index 0000000..2939c32 --- /dev/null +++ b/mock-server/schema.graphql @@ -0,0 +1,28 @@ +type Query { + posts: [Post!]! + post(id: ID!): Post + me: User +} + +type Mutation { + createPost(title: String!, body: String!): Post! +} + +type User implements Node { + id: ID! + name: String! + email: String! + avatarUrl: String +} + +type Post implements Node { + id: ID! + title: String! + body: String! + createdAt: String! + author: User! +} + +interface Node { + id: ID! +} diff --git a/package.json b/package.json index cea072a..d73cdd9 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,68 @@ { - "name": "rspack-rescript-react", - "private": true, - "version": "1.0.0", - "scripts": { - "dev": "concurrently \"bun run res:dev\" \"rspack serve\"", - "build": "cross-env NODE_ENV=production rspack build", - "res:build": "rescript build", - "res:dev": "rescript watch", - "res:clean": "rescript clean", -"prepare": "husky", - "commit": "git-cz", - "format:check": "biome check .", - "format:write": "biome format . --write", - "lint:check": "biome lint .", - "lint": "biome lint --write .", - "test": "vitest run", - "test:watch": "vitest" - }, - "dependencies": { - "@emotion/css": "^11.13.5", - "@emotion/server": "^11.11.0", - "@rescript/core": "1.6.1", - "@rescript/react": "0.14.2", - "react": "^19.2.5", - "react-dom": "^19.2.5", - "rescript": "12.2.0" - }, - "devDependencies": { - "@biomejs/biome": "^2.4.11", - "@commitlint/cli": "^20.5.0", - "@commitlint/config-conventional": "^20.5.0", - "@commitlint/cz-commitlint": "^20.5.1", - "@rspack/cli": "1.7.11", - "@rspack/core": "^1.7.11", - "@rspack/plugin-react-refresh": "1.6.2", - "@svgr/webpack": "^8.1.0", - "@testing-library/dom": "^10.4.1", - "@testing-library/jest-dom": "^6.9.1", - "@testing-library/react": "^16.3.2", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "commitizen": "^4.3.1", - "concurrently": "^9.2.1", - "cross-env": "^10.1.0", - "husky": "^9.1.7", - "inquirer": "^13.4.1", - "jsdom": "^29.0.2", - "typescript": "^6.0.2", - "vitest": "^4.1.4" - }, - "config": { - "commitizen": { - "path": "@commitlint/cz-commitlint" - } - } + "name": "rspack-rescript-react", + "private": true, + "version": "1.0.0", + "scripts": { + "dev": "concurrently \"bun run res:dev\" \"rspack serve\" \"bun run dev:server\"", + "dev:server": "node mock-server/index.js", + "build": "cross-env NODE_ENV=production rspack build", + "relay": "rescript-relay-compiler", + "relay:watch": "rescript-relay-compiler --watch", + "res:build": "rescript build", + "res:dev": "rescript watch", + "res:clean": "rescript clean", + "prepare": "husky", + "commit": "git-cz", + "format:check": "biome check .", + "format:write": "biome format . --write", + "lint:check": "biome lint .", + "lint": "biome lint --write .", + "test": "vitest run", + "test:watch": "vitest" + }, + "dependencies": { + "@emotion/css": "^11.13.5", + "@emotion/server": "^11.11.0", + "@rescript/core": "1.6.1", + "@rescript/react": "0.14.2", + "react": "^19.2.5", + "react-dom": "^19.2.5", + "react-relay": "20.1.1", + "relay-runtime": "20.1.1", + "rescript": "12.2.0", + "rescript-relay": "4.4.1" + }, + "devDependencies": { + "@biomejs/biome": "^2.4.11", + "@commitlint/cli": "^20.5.0", + "@commitlint/config-conventional": "^20.5.0", + "@commitlint/cz-commitlint": "^20.5.1", + "@rspack/cli": "1.7.11", + "@rspack/core": "^1.7.11", + "@rspack/plugin-react-refresh": "1.6.2", + "@svgr/webpack": "^8.1.0", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "commitizen": "^4.3.1", + "concurrently": "^9.2.1", + "cross-env": "^10.1.0", + "graphql": "16.11.0", + "graphql-yoga": "5.12.0", + "husky": "^9.1.7", + "inquirer": "^13.4.1", + "jsdom": "^29.0.2", + "typescript": "^6.0.2", + "vitest": "^4.1.4" + }, + "config": { + "commitizen": { + "path": "@commitlint/cz-commitlint" + } + }, + "trustedDependencies": [ + "rescript-relay" + ] } diff --git a/relay.config.js b/relay.config.js new file mode 100644 index 0000000..b232fb1 --- /dev/null +++ b/relay.config.js @@ -0,0 +1,6 @@ +module.exports = { + src: "./src", + schema: "./mock-server/schema.graphql", + artifactDirectory: "./src/__generated__", + language: "rescript", +}; diff --git a/rescript.json b/rescript.json index dea9f76..8bb2d9a 100644 --- a/rescript.json +++ b/rescript.json @@ -13,7 +13,8 @@ } ], "suffix": ".bs.js", - "dependencies": ["@rescript/core", "@rescript/react"], + "dependencies": ["@rescript/core", "@rescript/react", "rescript-relay"], + "ppx-flags": ["rescript-relay/ppx"], "jsx": { "version": 4, "mode": "automatic" diff --git a/src/App.res b/src/App.res index 27f4431..0b5b344 100644 --- a/src/App.res +++ b/src/App.res @@ -60,22 +60,24 @@ Emotion.Css.injectGlobal(` module App = { @react.component let make = () => { -
- -
- -
-
- - {React.string("Built with Rspack + ReScript + React + Bun")} - -
-
+ +
+ +
+ +
+
+ + {React.string("Built with Rspack + ReScript + React + Bun")} + +
+
+
} } diff --git a/src/__generated__/PostsPageQuery_graphql.res b/src/__generated__/PostsPageQuery_graphql.res new file mode 100644 index 0000000..88dbeb2 --- /dev/null +++ b/src/__generated__/PostsPageQuery_graphql.res @@ -0,0 +1,252 @@ +/* @sourceLoc PostsPage.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + type rec response_posts_author = { + name: string, + } + and response_posts = { + author: response_posts_author, + body: string, + createdAt: string, + @live id: string, + title: string, + } + type response = { + posts: array, + } + @live + type rawResponse = response + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + + +type queryRef + +module Internal = { + @live + let variablesConverter: dict>> = %raw( + json`{}` + ) + @live + let variablesConverterMap = () + @live + let convertVariables = v => v->RescriptRelay.convertObj( + variablesConverter, + variablesConverterMap, + None + ) + @live + type wrapResponseRaw + @live + let wrapResponseConverter: dict>> = %raw( + json`{}` + ) + @live + let wrapResponseConverterMap = () + @live + let convertWrapResponse = v => v->RescriptRelay.convertObj( + wrapResponseConverter, + wrapResponseConverterMap, + null + ) + @live + type responseRaw + @live + let responseConverter: dict>> = %raw( + json`{}` + ) + @live + let responseConverterMap = () + @live + let convertResponse = v => v->RescriptRelay.convertObj( + responseConverter, + responseConverterMap, + None + ) + type wrapRawResponseRaw = wrapResponseRaw + @live + let convertWrapRawResponse = convertWrapResponse + type rawResponseRaw = responseRaw + @live + let convertRawResponse = convertResponse + type rawPreloadToken<'response> = {source: Nullable.t>} + external tokenToRaw: queryRef => rawPreloadToken = "%identity" +} +module Utils = { + @@warning("-33") + open Types +} + +type relayOperationNode +type operationType = RescriptRelay.queryNode + + +let node: operationType = %raw(json` (function(){ +var v0 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "title", + "storageKey": null +}, +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "body", + "storageKey": null +}, +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null +}, +v4 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "PostsPageQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Post", + "kind": "LinkedField", + "name": "posts", + "plural": true, + "selections": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v3/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "author", + "plural": false, + "selections": [ + (v4/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "PostsPageQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Post", + "kind": "LinkedField", + "name": "posts", + "plural": true, + "selections": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v3/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "author", + "plural": false, + "selections": [ + (v4/*: any*/), + (v0/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "140268a5af4c6d335c5ea434cf85de18", + "id": null, + "metadata": {}, + "name": "PostsPageQuery", + "operationKind": "query", + "text": "query PostsPageQuery {\n posts {\n id\n title\n body\n createdAt\n author {\n name\n id\n }\n }\n}\n" + } +}; +})() `) + +@live let load: ( + ~environment: RescriptRelay.Environment.t, + ~variables: Types.variables, + ~fetchPolicy: RescriptRelay.fetchPolicy=?, + ~fetchKey: string=?, + ~networkCacheConfig: RescriptRelay.cacheConfig=?, +) => queryRef = ( + ~environment, + ~variables, + ~fetchPolicy=?, + ~fetchKey=?, + ~networkCacheConfig=?, +) => + RescriptRelayReact.loadQuery( + environment, + node, + variables->Internal.convertVariables, + { + fetchKey, + fetchPolicy, + networkCacheConfig, + }, + ) + +@live +let queryRefToObservable = token => { + let raw = token->Internal.tokenToRaw + raw.source->Nullable.toOption +} + +@live +let queryRefToPromise = token => { + Promise.make((resolve, _reject) => { + switch token->queryRefToObservable { + | None => resolve(Error()) + | Some(o) => + open RescriptRelay.Observable + let _: subscription = o->subscribe(makeObserver(~complete=() => resolve(Ok()))) + } + }) +} diff --git a/src/__generated__/RelaySchemaAssets_graphql.res b/src/__generated__/RelaySchemaAssets_graphql.res new file mode 100644 index 0000000..49198ff --- /dev/null +++ b/src/__generated__/RelaySchemaAssets_graphql.res @@ -0,0 +1,31 @@ +/* @generated */ +@@warning("-30") + +@live @unboxed +type enum_RequiredFieldAction = + | NONE + | LOG + | THROW + | FutureAddedValue(string) + + +@live @unboxed +type enum_RequiredFieldAction_input = + | NONE + | LOG + | THROW + + +@live @unboxed +type enum_CatchFieldTo = + | NULL + | RESULT + | FutureAddedValue(string) + + +@live @unboxed +type enum_CatchFieldTo_input = + | NULL + | RESULT + + diff --git a/src/pages/PostsPage.res b/src/pages/PostsPage.res index 72f9b89..9323ac4 100644 --- a/src/pages/PostsPage.res +++ b/src/pages/PostsPage.res @@ -1,4 +1,68 @@ open Emotion.Css +open Emotion.Utils + +module PostsQuery = %relay(` + query PostsPageQuery { + posts { + id + title + body + createdAt + author { + name + } + } + } +`) + +module PostCard = { + module Typography = Typography.Typography + module Card = Card.Card + + @react.component + let make = (~title, ~body, ~authorName, ~createdAt) => { + + + {React.string(title)} + + + {React.string(body)} +
+ {React.string(authorName)} + {React.string(createdAt)} +
+
+
+ } +} + +module PostsList = { + module Typography = Typography.Typography + + @react.component + let make = () => { + let data = PostsQuery.use(~variables=()) + +
+ {data.posts + ->Array.map(post => { + + }) + ->React.array} +
+ } +} module Typography = Typography.Typography @@ -8,14 +72,16 @@ let make = () => { "padding": "4rem 1rem", "maxWidth": "800px", "margin": "0 auto", - "textAlign": "center", })
{React.string("Posts")} - {React.string("Data fetching with Relay will be added here.")} + className={css({"marginTop": "0.5rem", "marginBottom": "2rem", "color": Color.textSecondary})}> + {React.string("Data fetched from the mock GraphQL server via Relay.")} + {React.string("Loading posts...")} }> + +
} diff --git a/src/relay/RelayEnv.res b/src/relay/RelayEnv.res new file mode 100644 index 0000000..6cea028 --- /dev/null +++ b/src/relay/RelayEnv.res @@ -0,0 +1,35 @@ +@val external fetch: (string, {..}) => promise<{..}> = "fetch" + +let fetchQuery: RescriptRelay.Network.fetchFunctionPromise = async ( + operation, + variables, + _cacheConfig, + _uploadables, +) => { + let body = JSON.stringifyAny({ + "query": operation.text, + "variables": variables, + })->Option.getOr("{}") + + let response = await fetch( + "http://localhost:4000/graphql", + { + "method": "POST", + "headers": { + "content-type": "application/json", + "accept": "application/json", + }, + "body": body, + }, + ) + await response["json"]() +} + +let network = RescriptRelay.Network.makePromiseBased(~fetchFunction=fetchQuery) + +let environment = RescriptRelay.Environment.make( + ~network, + ~store=RescriptRelay.Store.make( + ~source=RescriptRelay.RecordSource.make(), + ), +) From d9827e2937aa7d397cd50891f9b9dab42ee0b328 Mon Sep 17 00:00:00 2001 From: Antonette Caldwell <18711313+acald-creator@users.noreply.github.com> Date: Mon, 13 Apr 2026 02:22:02 -0500 Subject: [PATCH 2/2] fix: make GraphQL endpoint configurable and add error boundary Use GRAPHQL_ENDPOINT env var (defaults to localhost:4000/graphql in dev). Add RescriptReactErrorBoundary to PostsPage that shows a helpful "server not running" message when the mock server is unavailable (e.g. on Vercel deployment). --- rspack.config.js | 3 +++ src/pages/PostsPage.res | 42 ++++++++++++++++++++++++++++++++++++++--- src/relay/RelayEnv.res | 3 ++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/rspack.config.js b/rspack.config.js index f39caee..9eaaea0 100644 --- a/rspack.config.js +++ b/rspack.config.js @@ -12,6 +12,9 @@ module.exports = { "process.env.NODE_ENV": JSON.stringify( isProduction ? "production" : "development", ), + "process.env.GRAPHQL_ENDPOINT": JSON.stringify( + process.env.GRAPHQL_ENDPOINT || "http://localhost:4000/graphql", + ), }), !isProduction && new ReactRefreshPlugin(), ].filter(Boolean), diff --git a/src/pages/PostsPage.res b/src/pages/PostsPage.res index 9323ac4..4843fa0 100644 --- a/src/pages/PostsPage.res +++ b/src/pages/PostsPage.res @@ -64,6 +64,39 @@ module PostsList = { } } +module ServerUnavailable = { + module Typography = Typography.Typography + module Card = Card.Card + + @react.component + let make = () => { + + + + {React.string("GraphQL Server Not Running")} + + + {React.string( + "The Posts page requires the mock GraphQL server. Start it locally with:", + )} + + + {React.string("bun run dev:server")} + + + + } +} + module Typography = Typography.Typography @react.component @@ -80,8 +113,11 @@ let make = () => { className={css({"marginTop": "0.5rem", "marginBottom": "2rem", "color": Color.textSecondary})}> {React.string("Data fetched from the mock GraphQL server via Relay.")} - {React.string("Loading posts...")} }> - - + }> + {React.string("Loading posts...")} }> + + + } diff --git a/src/relay/RelayEnv.res b/src/relay/RelayEnv.res index 6cea028..2dac3f0 100644 --- a/src/relay/RelayEnv.res +++ b/src/relay/RelayEnv.res @@ -1,4 +1,5 @@ @val external fetch: (string, {..}) => promise<{..}> = "fetch" +@val external graphqlEndpoint: string = "process.env.GRAPHQL_ENDPOINT" let fetchQuery: RescriptRelay.Network.fetchFunctionPromise = async ( operation, @@ -12,7 +13,7 @@ let fetchQuery: RescriptRelay.Network.fetchFunctionPromise = async ( })->Option.getOr("{}") let response = await fetch( - "http://localhost:4000/graphql", + graphqlEndpoint, { "method": "POST", "headers": {