From 9da49ee1244b7e02a0ef47897e30bffa9a1f4cc0 Mon Sep 17 00:00:00 2001 From: Chad Freeman Date: Sun, 12 Jan 2025 20:25:21 -0500 Subject: [PATCH] swap out monaco and babel-walk with codemirror and @babel/traverse --- .prettierrc | 1 + bun.lockb | Bin 56532 -> 67540 bytes bunfig.toml | 2 + package.json | 11 +- postcss.config.js | 4 +- src/app.css | 16 +- src/app.d.ts | 2 +- src/lib/CodeEditor.svelte | 174 +++--------------- src/lib/CodeEditorOld.svelte | 147 +++++++++++++++ src/lib/build/esbuild.ts | 14 +- src/lib/components/Tab.svelte | 16 +- src/lib/editorcontext/sprig.d.ts | 79 -------- src/lib/provider/Provider.ts | 40 ++-- src/lib/text-editor/Tooltip.svelte | 6 + src/lib/text-editor/babel.ts | 71 +++++++ src/lib/text-editor/context/sprig.d.ts | 84 +++++++++ .../context}/sprigsy.d.ts | 3 +- src/lib/text-editor/extensions/babel.ts | 0 src/lib/text-editor/extensions/typescript.ts | 62 +++++++ src/routes/+layout.svelte | 4 +- src/routes/+layout.ts | 5 +- src/routes/+page.svelte | 13 +- svelte.config.js | 9 +- vite.config.ts | 6 +- 24 files changed, 478 insertions(+), 291 deletions(-) create mode 100644 bunfig.toml create mode 100644 src/lib/CodeEditorOld.svelte delete mode 100644 src/lib/editorcontext/sprig.d.ts create mode 100644 src/lib/text-editor/Tooltip.svelte create mode 100644 src/lib/text-editor/babel.ts create mode 100644 src/lib/text-editor/context/sprig.d.ts rename src/lib/{editorcontext => text-editor/context}/sprigsy.d.ts (79%) create mode 100644 src/lib/text-editor/extensions/babel.ts create mode 100644 src/lib/text-editor/extensions/typescript.ts diff --git a/.prettierrc b/.prettierrc index 3f7802c..ada5e7c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,7 @@ { "useTabs": true, "singleQuote": true, + "semi": false, "trailingComma": "none", "printWidth": 100, "plugins": ["prettier-plugin-svelte"], diff --git a/bun.lockb b/bun.lockb index a89b87f8939176a5390c82fbb0c3f77d801607c0..43584e3acfec84a816c92a6538e9d02629123ee3 100755 GIT binary patch delta 16078 zcmeHucUV-(()XNU1{oAVB+LK`2&jk*Im;kM6bvgMN>ajrAZZB-C=8fUG4&ci#eg}k zBDjjEsJrGhtQgj?x~ppryM|Rv@2}6yVP?I0-|yb<`|kVCd!DDds=KPIt5fv}buR4D zx-eHTPikM-XW0eQqhCpAyEjcs_yt$z{P^N^O`lc_k6s(+M_3w7 zUC+|0qz#W(lF7`U*->hf(j2(VJ{W#1Z)g`TVNyL zW`Pp_uEOV4c)tp7QsG4^JV}K!f!m{gv=S>y2B-==RoE8T5CVoO%v0efTFUZkDx95} zmX?>rce96%ojy4<&oXWNYDW?Pbun4#gzO9q{ug9O(h0OdDhB5A!SJLOdM1g0am4SZ_h z&dy3pLc8*K*2p^pV`>#8dP<_?Q5PlS6tEQpHUZN)p8|}!CCR`ThLQombk6O8shln_ zT??xqgs~|}P039`n>@awva7jqS#j}ca^6zp=~((<%TYsPoamTi(e(mBEwuxt4G4j$ z;`>tNqB;vqC$R>Y@|OTp`C?!?2g$&6Qlo)s15;rL9pkAm0>fQ0E+to%5{U)Ek%UuAvtg`LUYRe3)@WwRHNr*>m-SUssZ z@|*-(DW0u%5 zz#~mKe#JDM6Z4x*cgGJaessBb_m10>&VS!#dtRri`YSX4>T9HR$zl3|^4nX}A8k4J zH0Prh?`YDnGk5ni-soRwu|ntK*>I^&se9lnpOBM_@(-bmc% zy}8~dVZxJcqdV9PxYWq}NrGDS^tRS>a@cf4`_M!)!x^hD4msWTsAad+3%(=}A*Xl>26t(+P1OecRtP)xVf4M(2W>zm%4 zHTjI?>tU5vbFMYaaW#9L{&-_>roFKTB!Or0=Il-9}XKRdw6@;!(KzehYTtw`=$H8llF4$dY)v7f*1waBMM+1kvF0Mei)zl>dKhe zq(C=-`I+p|4d7d7k!D>PKS_)Dww5t#NkQuX;W{CYH<%Q)_7lDU6~aT?_T0h3conap$y97g?&opoajyL|HYdh1v$HpVAbTdf&E(0KTgq zX=vSp(ItiY0W{l(mC(gLP*Q_is0A(5MULXzw;_e?WWvpDdAumnVAMl^Wj2x&weu5> z0u@gD+p|ScY>_?|XDCa>gNk9P1E5k^sw=ie97~mfQkMM*N+~x4PB59})`60fBI6!R zd$QL!K!BYzie+2@r4;srzfxK;7t|=yVAw;@Qq&)QJAzhVsz`xJ0CR`zF$v&Xn~-J` znJCGG#~Xp2!jMLh7ju~umhlTH+KZV<_DBMlAITd@0AJUP_?pT1(PpI3OvcP5d&~m(LUYn=CKHW? zGa86WTBOm`OH`}M@kn56FQE|}5N1f%PZSBN2c)zKW9g+Qf!`TKbJ**Kq_L|5`BtRU zCI_W(1|awsr81Plner&;kgr8usJzG@&KVA)L_p2a z8;=~7qYVj3qlB%kcLt?lD5VX-P?b&_xbeO!Su7>BPGKoHZsfh#Pq+(IAnlOeOHh4O z(zJD@T|QPkUQe#Qzv(Cd$CVVB_~~s1#SR6_S9PBMmlg3fmGK8#lV)=nzu21iTF69O ztd$djQImLy?jYw4<>;E&OVptgm&0Un93uQ?5_!SWIaV za)Gc$h&AcO-|t5Dc9HS3+(|RgF?ZtIRmN|2Cxu;QLU#`yFO|IS=*K_dK??0<{0vXB z*Ip*tiO$ge@Yv0G4U{+V#c?>!XqrK+aexXCo4T(UbUF`sw|p5}}LCjN721K5!0nbqWZK z6&54ci%JWdK=q)M$PB&3*iv7F4u>GuldeO(*`VkSXbpXB(43P(42lAE0q}bCmW+pG z%U%>~0kAyT>vPx?oB$R7-@ppC>c3I(|4}`(kAsBz2=@AqW6a0D-7ud#mM&J%r7;db zS5P6VONr^k6{+%?m`-%Ds+?kaB1{3$@~J934Vdbi37~q)0raAn=H~%uyNmJQz*by> z4816(iYipN5}00^n2-E2w)FFuHoOu*!c8?#6h(0jR-u z0QAztbaL*orT+?6Zox&;JGT_tjfO!rWeIR03VfUeJz@(Fs-Mp z%G0vHxgFa6f7tI(8(RF9;(x;bXt*84|D69}#{sAMzvB4**YEtV-@&^1zxO+1+12-- z@jKNWJlpq_y?=AQ+r4vh56ay?o=ljPT6U{Ix8zW4Zih?1uH9O8V0i8=_qo6KzHrj0 zOF!Qo1;+JyIg4NYIB0xKdWW;}SDg*d)Wi%3(pGdi_F?&oNqH$V@`q_h2SypaO(~nU z%;?~`XDR(1vRymyLqu!8nwVDP5itD+ho?=)TaS2qIsI%EtGVy(d_L1ok`-bkHJLKfRrgKg8QQ2+!Uf6%iuRJqlyrgQ* zJKdLNBUY_AHR9OKu!oLKhI4;bw5VsB&+O@8il!!}jsN9{yv4Z_MHsI^l=68E!g!U~AM-(}&fOZ8WSKq-mXA z)f|ud9vjaOJone2N4$xbyXri+XsRf^NTLnHx5{3A7ye_`w!N>1N@^A6MrN+pufE&* z&Ag5MCz`zuXO2}ZJhprbc?|2uRoZB`Pt*Bn!jRKs=^oE}ZKu6B^p|H)@0}CL z@aE+GZHEv$k$dg`0yNd%7#(ll##g@Vh4eP$rv~F?G#6M z#EQnl@1mdIYE!g*@cNg}!+W^YB}YB%ee9L%xsWEG?Hep^Cmau0H_fc`t7kEf&)Rp< z)jIQ2)cftW9bJQV-VE4%^0cXjb)lNpt$VC{(Rs$WT#qYj%f|@A?(F;Zk!jxHD$%u` zD|tWtKDvHr*Y~Zo{g+AFe~4ab(0uR6%b!dhce>;7` zdCvN{T`|Ldtjb)`#qZ{{RV53~4!?eK#leLp4OYwC)9u&hml~Y*saU$VUwg;sx38vE z$Y*L;7ollgxZZ5x{hu~RT$BgCZ$tXkNpE-iFeShBlI`PLA2v3bGOIRy&CjtNbtIV! z>vUH&ZR-5`-HD~6<5OoeT*+)KOKQ0DD~Smcht$ukmyMI#4YVmR-DkAuK$UB>%gLai zG5WnH-;F$4bai{XTi-kmeK^Xv?Av+fH?w!vy%F@NEe+?@M%{Ti;6$%ww>7LAN!ksF zAmZ@0WZjT~OceQJNCXp21`Lg0V#q3_vE&WXQRJ(yBAC%+Bhom+42xjm$qu9mL=+mK zNYw1%frY=?Of7j+>v}Hh=7PNy3r>_q@{J~Ry7HY z`xNhY|1dds+K6%ci?*NpYh|_2SHm{Brrv3PhRtq@6`Yvxr23fW9jCbb*QRz=`G<9r zLR|YWE=D)ZN}09~@|=4O4SPFqxum}T&-uZ9758ICwHLHKaFsM18>pc;iCD))Fv+AK zE`r<}sTZ<+`19gDyXwm3*c|f+_B)iq+`G5i>7m~)1N}um2R__=G~i@9^4Q&|V% zYS`=?5^+nMbx^=x`yg)h@y(S#CTXZnA??B<$dX7sk{1@tj3tf81x4u*yYOHpoqQc0 z!DNu*NHdA`@CYW06d?VYoI{#T>?0zW98!ujms~-bM_fikFylxW((&XL(tP4GGJ+`} z^G9ONM(dH6BZHX-DMPxD+(NpD_#{R!i^+VXOUQks z6(mp|!Bmn8q)W*kNSBcTNfFF)vMMP;QKh*8N|vrs0Lw1DEZzn^hV;$K%et zijZS(`#TMa-4ijH;bHJ zT#?*2pwB=j(Y%qFDZ|Z!??}^!`;J@s?opIyJ@I^H(>Gj0aW$tESkU);SaF2l`uA?# zY`XPo&95IkRrWM2chcZU(7k`^JM)d^HIBN^Cur@`q1j|w~hxVPpzL9^1Pwl z%uNn2);(^uTI<*3?8@+NdTouJYgUV9d*3fk(ix?pcP*zBSTMjazr1WQX`Sq^;AVh( zWkAIQ9}auvKA!65@teKQfW74gml~ca;^$PK%(ppt^yJ3AuPTk!*PR$LQOaG$X z0j+MWu(#ZlRrkHc;N{UivA1T7(P($QX1gz3w$@e5-8VZh^Zm9%3&&jlxlHl;$^6wN zLLaBKtseE>RO;zJbjqLO?^zrjDP4Rh(D2#*89C8Y=E{$`>^|+{_*QyIL-7Vp#UpN} zybIJG)~UN)w+W3WKc1{^+ZT^MqGBCXj*6yy&t(3)o{JsFZVwkrq$!}6D<=?Fv3=zGr=KC0=l-@2js zt`)v-QdWz?mFYUhS~kkBp8urXv`ihLA>LDSm5LQXi5hYrq=-eWmjN@DT6_@EGs}@DxDbGc^G&0xkhA1Fism23!SP16&8(0Q>@=FUF43 zSb$R?=%%8^Q}Z?gHUY8$Ipob8H7pbn4l5Au5{Mjt^9c=%OeC%m7RWOan{>OaaivLl+TUOeFvuzU*S6Cd>hp z1L#c722fM^DxiEy(=s|m%K%FOl~hFlhzbB#c@bzj21@|n0OkW|B~Bp$y#PR0E|pyf zmzYu|CQm-GqN$GC6-6*^3;m(cM{OF$aeWy#U8k>MC_rE;?OshE3^M z*Lz3jXF5!8C~J?B(c~?WnCBy>hn)E-yNw%Kcbtcsu2N^IGp2+%eIrq91K$YztdXHd zEbgsYq{Gl%L2DcWHUZ`WL6p`wOFdcVL+#{3N5FBBdQzR#2hciPa0%O*n-m}3-h)H! zi--=nVFof^PkiiSZp1n{( zj0#-b4Qr7*ZI_E?8~FNon(%3Ln7V&*hD=)M>X?bD2B=!R*}2AJ#)rYE>Lz8Ya%XT? zL5e|tQFFclbCld#_=klv7Gi7EnC}!>-nrJ_$B5~G5<295eDY+GnBSjIbQZfZhl$@} zi8&X==+IQ1eQxZ|Xg(b*S8CcdlDSyo$;At%?CG(=T|51E0fR2OV9wcnX9%r#7v=uB zD&SSUnqw#+`xlEnxe!FpkW+Q57VIii3vfY-&b=x}?bg=kt2qO3axM{DsKOdcW(c;7 z8P(1=UoDU+AU&6eJ-9f?W37fR?sqT!kXnF?loU5Ny9_(wDOYngk@6)Hb1t&->g1$; zE{lF{RP)c1#w8NwcXD-!#Da^!_4q}g3VS#vc+3M~3_G~{j|0Z!+D&Y&-l8~ih3of!Wpw(AN*)xtOs>S@;l9Huj z4=xmSQt*ng4>#(Ds0FxSRsCPjxpaSb@|~J9hn!w2@%(gG8z^@*JOLXuiUaiFqFc$n z<%`4y%ziiqGgzxH_54;91;wyst_9a)~(?uDYl$ zxLU{S$Y0=tiy3w)Cr_74JpY*?N;f2nWW9k>rNEh|RHfje zQMqV7NK%IhRa^ip7eA=x)LAH_7`X^SHHV9Jq7Ie~t;2;3a}k%| z;1HF%<1VwKa&dAomwd%PZ|KVt;flrgd9zs)xFBRMh*RAmE=*Y&=BX&OP_sVUBi4j3 zkI$Dm|3_1#U_(%0f+r5cFD*LPFHRBL*UwJTmq(7}aKYH|Tr{g{6mTB?i|X9yV&K&M zqc(P%nUD`lJ#kQbEbA-tvQ~yFb8+x1>`J;jOqItQFfxCrg0l2%dgI39ZFBMTX|TSw zn>CH?={0N8YelT$Y9}@>rzK>a+aA;{vNc;`%-gAAbk&?sd#C1nx;@k!F5X-fyKDCY zETT&thu1&$qMOnJ9`Rjc#&5PIH`f_iIZM5GTrj%b_v=Etn5PP$19zPsQXgKF9k~Ig z#>H$~xEXreowZ#K0T1jNEDGH37_M|xtm>?EJ8AaMMGl?cE#@-|Q9^w(7ufzJ{5NBR zCHjZeoKNq|)Eq8my@!=uY`=S}Jp?Vet6!F@ zD{-Om9z8t7z3rzZE&zYV!?1O`)`j$> z9JEjS%Ejn6g)cubX3&G<>PlP`|NRi*(8o;bK{ZDe=wEW&uV}P$-ttX`R_=F~{ZvejY>?k9lb+744&mz=?k z5?A%Ul$?cb?ymufE%Q^R*R*|KN0YA$(Sn- z%5LAdpcY_%5uj5)zxL{lbCVzQ86$U+SZ&20;!dVjyW&;+p6b5*5$+4txC+<6#oLnP z>JB7hO?TT7$kC?-`cR4!vt;4wYSXxVT4e@I72J$5O0+!5{xwN_15eUS zI%tKR7Uo4}uJcuV`VLqJy@-A9kvB`7)60djwRaDOtW>u~>vaQ{4T99JIq#|ZZq1UNWArIzU0 zVLT?%XW*Q&pbxv&+D-%u2GUNeJT3ROllxNw0`yiEkNL_@n18tw8n>Y)0uPnE%FXwp zeffM<%K3a>C`adn^2`W2LHO%?k)ZX?=2x&isJENq?Qx39Z~Gx%CDNl6zC^7L=ocRs zFHdvI&5j!<&(4weOvp@>r>A6RXJ$L4#bqQrrpAqn%Sp&i$;!>hO84!Vnv?C6lbbkd zR9sF$MnX@JPAo;vt&flGnOl%0&v9ZkjvCdXk}YLbIE_on>52b*ax=$gIH_B5%*|0} za8zN09pmM>aZ(r6yK~3!aXIM=zBjQ|KBPD%jFBgd<>(fJ9p#BBxtZBDRU6tE6Q|SW zK3|e>a&-C<%h83tN+9JIJCfRq<~4oyztNKPOwCS7OqP$Ar?KOdAa_iU%gRd0NG7)$ zEy%$`t!w0m1~3YB7ocCAailxdMVgyj__wi5$;j2rk4uq{*UabS#^wHPGIHc`*$HDb zMG`X8)8jG{b5vz^EpwI^m;AS?ae29!5Y9@I=gO(cGPQ9|nmm}TnT6pl-WUyPd78XX zo{dhWr)OqR73P`+Y;SiC@4{()`lluBq12OBw$P}Yh7}A6idgOLWL-lTX}{mC zX8YlH40-Z>aktNJb=EA-$zbbaUfoFGPuAv2_tD}gAP0AW#<79utdky>Mv)Kuw7Y)d zUm*8Mi6hPlSX}el4E!UCFB5)W&y3*4(cK(R%eu| zS<6#%9CI_r$}@84&NOeyQBygNBRwnGl|^-0v@{Eu7FuO2xqCHS6rYlT%J>(Ps?=vG zRvk(l-N>__ZAjarI)1y6ra4rz^50EIdc#0(t1t@WR?3q90&ZZ5 Al>h($ delta 8972 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 diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..bea1efe --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,2 @@ +[install.scopes] +"@jsr" = "https://npm.jsr.io" diff --git a/package.json b/package.json index c770d44..10141d1 100644 --- a/package.json +++ b/package.json @@ -15,20 +15,25 @@ }, "devDependencies": { "@babel/parser": "^7.26.5", + "@babel/traverse": "^7.26.5", + "@codemirror/lang-javascript": "^6.2.2", + "@std/async": "npm:@jsr/std__async", "@sveltejs/adapter-static": "^3.0.6", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.0", "@tailwindcss/postcss": "^4.0.0-beta.9", - "babel-walk": "^3.0.1", - "constrained-editor-plugin": "^1.3.0", + "@types/babel__traverse": "^7.20.6", + "@typescript/vfs": "^1.6.0", + "@valtown/codemirror-ts": "^2.3.1", + "codemirror": "^6.0.1", "daisyui": "^5.0.0-beta.1", "esbuild-wasm": "^0.24.2", - "monaco-editor": "^0.52.2", "prettier": "^3.3.2", "prettier-plugin-svelte": "^3.2.6", "sprig": "^1.1.3", "svelte": "^5.0.0", "svelte-check": "^4.0.0", + "svelte-codemirror-editor": "^1.4.1", "tailwindcss": "^4.0.0-beta.9", "typescript": "^5.0.0", "vite": "^5.4.11", diff --git a/postcss.config.js b/postcss.config.js index c5c819c..1e7a895 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,5 +1,5 @@ export default { plugins: { - '@tailwindcss/postcss': {}, + '@tailwindcss/postcss': {} } -}; +} diff --git a/src/app.css b/src/app.css index b932777..f406f04 100644 --- a/src/app.css +++ b/src/app.css @@ -11,11 +11,11 @@ color utility to any element that depends on these defaults. */ @layer base { - *, - ::after, - ::before, - ::backdrop, - ::file-selector-button { - border-color: var(--color-gray-200, currentColor); - } -} \ No newline at end of file + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentColor); + } +} diff --git a/src/app.d.ts b/src/app.d.ts index da08e6d..4e661d5 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -10,4 +10,4 @@ declare global { } } -export {}; +export {} diff --git a/src/lib/CodeEditor.svelte b/src/lib/CodeEditor.svelte index 791e1b3..d3a4d91 100644 --- a/src/lib/CodeEditor.svelte +++ b/src/lib/CodeEditor.svelte @@ -1,153 +1,39 @@ - -
+ + editor = e.detail} on:change={(e) => { + console.log(e) +}} bind:value {extensions} class="editor-container" /> - diff --git a/src/lib/CodeEditorOld.svelte b/src/lib/CodeEditorOld.svelte new file mode 100644 index 0000000..0f243ea --- /dev/null +++ b/src/lib/CodeEditorOld.svelte @@ -0,0 +1,147 @@ + + +
+ + diff --git a/src/lib/build/esbuild.ts b/src/lib/build/esbuild.ts index b083a69..0be93b5 100644 --- a/src/lib/build/esbuild.ts +++ b/src/lib/build/esbuild.ts @@ -1,23 +1,23 @@ -import { transform, initialize } from 'esbuild-wasm'; +import { transform, initialize } from 'esbuild-wasm' await initialize({ wasmURL: (await import('esbuild-wasm/esbuild.wasm?url')).default -}); +}) export async function buildProject(code: string, vanilla: boolean) { - let template = ''; + let template = '' if (vanilla) { template += `async function game(api) { ${code} } console.log("Made with Sprigsy") game({ addSprite, addText, afterInput, bitmap, clearInterval, clearText, clearTile, clearTimeout, color, getAll, getFirst, getGrid, getTile, height, map, onInput, playTune, setBackground, setInterval, setLegend, setMap, setPushables, setSolids, setTimeout, tilesWith, tune, width }) -`; +` } else { - throw new Error('not implemented'); + throw new Error('not implemented') } return await transform(template, { - loader: 'ts', - }); + loader: 'ts' + }) } diff --git a/src/lib/components/Tab.svelte b/src/lib/components/Tab.svelte index 477b6dc..c4a2585 100644 --- a/src/lib/components/Tab.svelte +++ b/src/lib/components/Tab.svelte @@ -1,5 +1,5 @@
diff --git a/src/lib/editorcontext/sprig.d.ts b/src/lib/editorcontext/sprig.d.ts deleted file mode 100644 index ba51f4b..0000000 --- a/src/lib/editorcontext/sprig.d.ts +++ /dev/null @@ -1,79 +0,0 @@ -/** - * normal sprig api - * this is provided because your project type is - */ -declare namespace sprig { - export declare const VALID_INPUTS: readonly ['w', 's', 'a', 'd', 'i', 'j', 'k', 'l']; - export type InputKey = (typeof VALID_INPUTS)[number]; - export interface AddTextOptions { - x?: number; - y?: number; - color?: string; - } - export declare class SpriteType { - type: string; - x: number; - y: number; - readonly dx: number; - readonly dy: number; - remove(): void; - } - export type Rgba = [number, number, number, number]; - export interface TextElement { - x: number; - y: number; - color: Rgba; - content: string; - } - export interface GameState { - legend: [string, string][]; - texts: TextElement[]; - dimensions: { - width: number; - height: number; - }; - sprites: SpriteType[]; - solids: string[]; - pushable: Record; - background: string | null; - } - export interface PlayTuneRes { - end(): void; - isPlaying(): boolean; - } - // export declare const tones: Record; - // export declare const instruments: readonly ["sine", "triangle", "square", "sawtooth"]; - export type InstrumentType = (typeof instruments)[number]; - // export declare const instrumentKey: Record; - // export declare const reverseInstrumentKey: Record<"sine" | "triangle" | "square" | "sawtooth", string>; - export type Tune = [number, ...(InstrumentType | number | string)[]][]; - export interface FullSprigAPI { - map(template: TemplateStringsArray, ...params: string[]): string; - bitmap(template: TemplateStringsArray, ...params: string[]): string; - color(template: TemplateStringsArray, ...params: string[]): string; - tune(template: TemplateStringsArray, ...params: string[]): string; - setMap(string: string): void; - addText(str: string, opts?: AddTextOptions): void; - clearText(): void; - addSprite(x: number, y: number, type: string): void; - getGrid(): SpriteType[][]; - getTile(x: number, y: number): SpriteType[]; - tilesWith(...matchingTypes: string[]): SpriteType[][]; - clearTile(x: number, y: number): void; - setSolids(types: string[]): void; - setPushables(map: Record): void; - setBackground(type: string): void; - getFirst(type: string): SpriteType | undefined; - getAll(type?: string): SpriteType[]; - width(): number; - height(): number; - setLegend(...bitmaps: [string, string][]): void; - onInput(key: InputKey, fn: () => void): void; - afterInput(fn: () => void): void; - playTune(text: string, n?: number): PlayTuneRes; - setTimeout(fn: TimerHandler, ms: number): number; - setInterval(fn: TimerHandler, ms: number): number; - clearTimeout(id: number): void; - clearInterval(id: number): void; - } -} diff --git a/src/lib/provider/Provider.ts b/src/lib/provider/Provider.ts index cd3eb64..6e3f077 100644 --- a/src/lib/provider/Provider.ts +++ b/src/lib/provider/Provider.ts @@ -1,30 +1,26 @@ -import { buildProject } from "$lib/build/esbuild" +import { buildProject } from '$lib/build/esbuild' enum Capability { - BuildToVite, - ProjectDB + BuildToVite, + ProjectDB } export default abstract class Provider { - constructor( - - ) { - - } + constructor() {} - abstract capabilities(): Capability[] + abstract capabilities(): Capability[] - /** - * Builds HTML project - */ - async buildHTML(input: string): Promise { - throw new TypeError("BuildToVite capability is not available") - } + /** + * Builds HTML project + */ + async buildHTML(input: string): Promise { + throw new TypeError('BuildToVite capability is not available') + } - /** - * Build JS - */ - async buildJS(input: string): Promise { - return (await buildProject(input, true)).code - } -} \ No newline at end of file + /** + * Build JS + */ + async buildJS(input: string): Promise { + return (await buildProject(input, true)).code + } +} diff --git a/src/lib/text-editor/Tooltip.svelte b/src/lib/text-editor/Tooltip.svelte new file mode 100644 index 0000000..14a57c7 --- /dev/null +++ b/src/lib/text-editor/Tooltip.svelte @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/src/lib/text-editor/babel.ts b/src/lib/text-editor/babel.ts new file mode 100644 index 0000000..0220cb7 --- /dev/null +++ b/src/lib/text-editor/babel.ts @@ -0,0 +1,71 @@ +import { debounce } from '@std/async' +import { parse } from '@babel/parser' + +let traverse: typeof import("@babel/traverse")['default'] + +export async function setupBabel() { + traverse = (await import("@babel/traverse")).default +} + +const disallowedIdentifiers = ['window', 'globalThis'] +type ASTState = { + disallowedWarnings: { identifier: string; loc: [number, number, number, number] }[] + errors: { reason: string; loc: [number, number, number, number] }[] +} + +export default debounce((code: string) => { + let ast + try { + ast = parse(code, { + plugins: ['typescript'] + }) + } catch { + return + } + const state: ASTState = { disallowedWarnings: [], errors: [] } + traverse(ast, { + MemberExpression: { + enter: (path, state) => { + if (path.node.optional) { + state.errors.push({ + reason: + 'optional chaining (?.) will work in the editor but it will not work on the sprig console', + loc: [ + path.node.loc?.start.line!, + path.node.loc?.start.column!, + path.node.loc?.end.line!, + path.node.loc?.end.column! + ] + }) + } + } + }, + Identifier: { + enter: (path, state) => { + if (disallowedIdentifiers.includes(path.node.name)) { + state.disallowedWarnings.push({ + identifier: path.node.name, + loc: [ + path.node.loc?.start?.line!, + path.node.loc?.start?.column!, + path.node.loc?.end?.line!, + path.node.loc?.end?.column! + ] + }) + } + } + }, + }, undefined, state) + state.disallowedWarnings.forEach((v) => { + monaco.editor.setModelMarkers(editor.getModel()!, editor.getId(), [ + { + message: `'${v.identifier}' is not allowed.`, + severity: monaco.MarkerSeverity.Error, + startLineNumber: v.loc[0], + startColumn: v.loc[1] + 1, + endLineNumber: v.loc[2], + endColumn: v.loc[3] + 1 + } + ]) + }) +}, 300) diff --git a/src/lib/text-editor/context/sprig.d.ts b/src/lib/text-editor/context/sprig.d.ts new file mode 100644 index 0000000..b16fe56 --- /dev/null +++ b/src/lib/text-editor/context/sprig.d.ts @@ -0,0 +1,84 @@ +/** + * basic sprig API + * this is provided because your project type is base + */ +declare global { + declare namespace sprig { + export declare const VALID_INPUTS: readonly ['w', 's', 'a', 'd', 'i', 'j', 'k', 'l'] + export type InputKey = (typeof VALID_INPUTS)[number] + export interface AddTextOptions { + x?: number + y?: number + color?: string + } + export declare class SpriteType { + type: string + x: number + y: number + readonly dx: number + readonly dy: number + remove(): void + } + export type Rgba = [number, number, number, number] + export interface TextElement { + x: number + y: number + color: Rgba + content: string + } + export interface GameState { + legend: [string, string][] + texts: TextElement[] + dimensions: { + width: number + height: number + } + sprites: SpriteType[] + solids: string[] + pushable: Record + background: string | null + } + export interface PlayTuneRes { + end(): void + isPlaying(): boolean + } + // export declare const tones: Record; + // export declare const instruments: readonly ["sine", "triangle", "square", "sawtooth"]; + export type InstrumentType = (typeof instruments)[number] + // export declare const instrumentKey: Record; + // export declare const reverseInstrumentKey: Record<"sine" | "triangle" | "square" | "sawtooth", string>; + export type Tune = [number, ...(InstrumentType | number | string)[]][] + export interface FullSprigAPI { + map(template: TemplateStringsArray, ...params: string[]): string + bitmap(template: TemplateStringsArray, ...params: string[]): string + color(template: TemplateStringsArray, ...params: string[]): string + tune(template: TemplateStringsArray, ...params: string[]): string + setMap(string: string): void + addText(str: string, opts?: AddTextOptions): void + clearText(): void + addSprite(x: number, y: number, type: string): void + getGrid(): SpriteType[][] + getTile(x: number, y: number): SpriteType[] + tilesWith(...matchingTypes: string[]): SpriteType[][] + clearTile(x: number, y: number): void + setSolids(types: string[]): void + setPushables(map: Record): void + setBackground(type: string): void + getFirst(type: string): SpriteType | undefined + getAll(type?: string): SpriteType[] + width(): number + height(): number + setLegend(...bitmaps: [string, string][]): void + onInput(key: InputKey, fn: () => void): void + afterInput(fn: () => void): void + playTune(text: string, n?: number): PlayTuneRes + setTimeout(fn: TimerHandler, ms: number): number + setInterval(fn: TimerHandler, ms: number): number + clearTimeout(id: number): void + clearInterval(id: number): void + } + } + +} + +export {}; \ No newline at end of file diff --git a/src/lib/editorcontext/sprigsy.d.ts b/src/lib/text-editor/context/sprigsy.d.ts similarity index 79% rename from src/lib/editorcontext/sprigsy.d.ts rename to src/lib/text-editor/context/sprigsy.d.ts index a3050e1..6ffda06 100644 --- a/src/lib/editorcontext/sprigsy.d.ts +++ b/src/lib/text-editor/context/sprigsy.d.ts @@ -1,4 +1,5 @@ /** + * THIS SHOULD NOT BE HERE * API for sprigsy * this is provided because your project has sprigsy v2 enabeled */ @@ -8,6 +9,6 @@ declare namespace sprigsy { * Retrieve a sprite key for the sprite name * @param name Sprite name */ - spriteKeyFor(name: string): string; + spriteKeyFor(name: string): string } } diff --git a/src/lib/text-editor/extensions/babel.ts b/src/lib/text-editor/extensions/babel.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/text-editor/extensions/typescript.ts b/src/lib/text-editor/extensions/typescript.ts new file mode 100644 index 0000000..02977ef --- /dev/null +++ b/src/lib/text-editor/extensions/typescript.ts @@ -0,0 +1,62 @@ +import { javascript } from '@codemirror/lang-javascript' +import { autocompletion } from '@codemirror/autocomplete' +import Tooltip from '../Tooltip.svelte' +import { mount, unmount } from 'svelte' +import { + createDefaultMapFromCDN, + createSystem, + createVirtualTypeScriptEnvironment +} from '@typescript/vfs' +import ts from 'typescript' +import { tsFacet, tsLinter, tsHover, tsAutocomplete, tsSync } from '@valtown/codemirror-ts' + +import sprigDeclarations from '$lib/text-editor/context/sprig.d.ts?raw' + +const fsMap = await createDefaultMapFromCDN({ target: ts.ScriptTarget.ES2022 }, '5.7.3', true, ts) +fsMap.set('lib.sprig.d.ts', sprigDeclarations) +const system = createSystem(fsMap) +const compilerOpts = {} +const env = createVirtualTypeScriptEnvironment(system, ['lib.sprig.d.ts'], ts, compilerOpts) + +console.log(fsMap.entries().toArray()) +const path = 'index.ts' + +export const typescriptExtensions = [ + javascript({ + jsx: false, + typescript: true + }), + tsFacet.of({ env, path }), + tsSync(), + tsLinter(), + autocompletion({ + override: [tsAutocomplete()], + + }), + tsHover({ + renderTooltip: (info) => { + console.log("rendering tooltip") + let tooltip: Tooltip; + const div = document.createElement('div') + return { + dom: div, + mount() { + tooltip = mount(Tooltip, { + target: div, + intro: true, + props: { + info + } + }) + }, + destroy() { + unmount(tooltip, { outro: true }) + } + } + } + }) +] + +export { + env +} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 3b7359a..5f8f30a 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,6 +1,6 @@ {@render children()} diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 0a06f03..9c1daa0 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -1,2 +1,3 @@ -export const csr = true; -export const prerender = true; \ No newline at end of file +export const csr = true +export const prerender = true +export const ssr = false diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index eae1fe2..7d9d521 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,8 +1,11 @@
@@ -56,3 +59,5 @@ This will have the game screen {/if}
+ + \ No newline at end of file diff --git a/svelte.config.js b/svelte.config.js index 4fbc867..89d00e0 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,18 +1,17 @@ -import adapter from '@sveltejs/adapter-static'; -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +import adapter from '@sveltejs/adapter-static' +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), - kit: { // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. // If your environment is not supported, or you settled on a specific environment, switch out the adapter. // See https://svelte.dev/docs/kit/adapters for more information about adapters. adapter: adapter() } -}; +} -export default config; +export default config diff --git a/vite.config.ts b/vite.config.ts index 8a4c5fd..0848c3c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,9 @@ -import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig } from 'vite'; +import { sveltekit } from '@sveltejs/kit/vite' +import { defineConfig } from 'vite' export default defineConfig({ plugins: [sveltekit()], build: { target: ['es2022'] } -}); +}) -- 2.39.5