cajonzero 0.0.0-stage → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -2
  3. package/dist/bin/cj0.d.ts +1 -0
  4. package/dist/bin/cj0.js +477 -0
  5. package/dist/bin/cj0.js.map +1 -0
  6. package/dist/config-BiQK9O_0.d.ts +278 -0
  7. package/dist/core.d.ts +109 -0
  8. package/dist/core.js +17918 -0
  9. package/dist/core.js.map +1 -0
  10. package/dist/index.d.ts +133 -0
  11. package/dist/index.js +27210 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/room-BVwLGGkm.d.ts +5225 -0
  14. package/dist/scaffold.d.ts +150 -0
  15. package/dist/scaffold.js +294 -0
  16. package/dist/scaffold.js.map +1 -0
  17. package/dist/serve.d.ts +113 -0
  18. package/dist/serve.js +27215 -0
  19. package/dist/serve.js.map +1 -0
  20. package/dist/ui/assets/A-BFmQQnEZ.png +0 -0
  21. package/dist/ui/assets/B-7CK86GBa.png +0 -0
  22. package/dist/ui/assets/Code-New-Roman-Bold-DHej6F6U.woff +0 -0
  23. package/dist/ui/assets/arrow-4n-TatjQ.png +0 -0
  24. package/dist/ui/assets/crouch-2Aeej1uw.png +0 -0
  25. package/dist/ui/assets/fly-Dl5t170A.png +0 -0
  26. package/dist/ui/assets/fly-reversed-E3sWxK74.png +0 -0
  27. package/dist/ui/assets/index-CsaJDw8o.js +4405 -0
  28. package/dist/ui/assets/index-W1HlDaw6.css +2 -0
  29. package/dist/ui/assets/jump-Al-21z7o.png +0 -0
  30. package/dist/ui/assets/main-BgFJ4-4_.js +7108 -0
  31. package/dist/ui/assets/particle.worker-D6dE_8ka.js +1 -0
  32. package/dist/ui/assets/photo-image-N0oLY1qP.png +0 -0
  33. package/dist/ui/assets/rubik-v20-latin-regular-B0q52jxy.woff2 +0 -0
  34. package/dist/ui/assets/script-D_l9sqM8.js +1 -0
  35. package/dist/ui/assets/voxel.worker-CvX1GY4o.js +1 -0
  36. package/dist/ui/cajonzero-assets/blobs/-4Z3u_vlCPmpCRsG-tr5eLI4On13qNTpgnT-DArvjPo +0 -0
  37. package/dist/ui/cajonzero-assets/blobs/-PwWZ9AEpzk377FQDI94jsphx1MzasVJd5s4zFZDhcU +0 -0
  38. package/dist/ui/cajonzero-assets/blobs/0uyvWiAlEwsxmi0aHE_bJEt2Czve3sfSpfF5T-8zWEo +0 -0
  39. package/dist/ui/cajonzero-assets/blobs/17CzAKUuiO68ymvOPlXf7da1QdhU78fcsKHtC6l850k +0 -0
  40. package/dist/ui/cajonzero-assets/blobs/1Sz9b2RJLB_LTdrWxGCy_1gx051sihM7Msn1OPg1uZY +0 -0
  41. package/dist/ui/cajonzero-assets/blobs/2SICLQuRD8nYoThtljS24xnVHMMaMFVQkTqT7YpUWyo +0 -0
  42. package/dist/ui/cajonzero-assets/blobs/2re1r3Sq3BW4g_kYo-2WC_u07vNXFYEn5fhUJDmD_lA +0 -0
  43. package/dist/ui/cajonzero-assets/blobs/3TITLhARLguVu71MnxN91pt5s8g301Ox3XPzzEbQ6bE +0 -0
  44. package/dist/ui/cajonzero-assets/blobs/3t4Jqs6gaJacqhnYDgqZ2vYS7JaPgRlUHB-By0rvqGI +0 -0
  45. package/dist/ui/cajonzero-assets/blobs/3wkhe7Ans_MZGGPsPTvtS7-q_pZdwHwChZJqcGH2Cr4 +0 -0
  46. package/dist/ui/cajonzero-assets/blobs/4EalxePRBTvHC2WVL7jWpab9vk7znXwq-tk0wZM3zAw +0 -0
  47. package/dist/ui/cajonzero-assets/blobs/4jRcLv0pBJE9AjT8Jc9jZDDeUfc_RHzVfsJZyeMuaok +0 -0
  48. package/dist/ui/cajonzero-assets/blobs/4otrUC6iqWA4J7gzPlGy9MbuPzYpYEUKcKMkaNDcRtw +0 -0
  49. package/dist/ui/cajonzero-assets/blobs/57m8K7_P-oRkudRkii4mjK2HgQ1qRL5DSVn1JRHCrUc +0 -0
  50. package/dist/ui/cajonzero-assets/blobs/5cwYkZ2jXAx4nXS0eZ4Rf6pInNuohcrZJzePgx_WkzU +0 -0
  51. package/dist/ui/cajonzero-assets/blobs/5oJbXf0svH-YNSfnjXrPtuq9bY6XYa4gcagb_5a9rQc +0 -0
  52. package/dist/ui/cajonzero-assets/blobs/6Vv-ANt6YO7b-e8gUkS1T4eDXPeMDv3sSS1Fys_h0S8 +0 -0
  53. package/dist/ui/cajonzero-assets/blobs/6rwaXC7s1n3549pYT9Eh_9qeBK3R_p6rKBLHt7BPcsU +0 -0
  54. package/dist/ui/cajonzero-assets/blobs/7xhQlsJCS24FVMSPcr62lAC83e5Xeg_Z77kAa2Cai3U +0 -0
  55. package/dist/ui/cajonzero-assets/blobs/9gtCoNxXqTSG7QKR1FpbpF0ySeNvA-JMrlq17Qm-L2k +0 -0
  56. package/dist/ui/cajonzero-assets/blobs/AfkW1bfj2sZ2x0QleyXGTAAICRTtJynxj9qYFftu0cc +0 -0
  57. package/dist/ui/cajonzero-assets/blobs/BtoygkjjKTbFkCz-YqoBuYw26F6Bm6ZYGQYe_j9Ll44 +0 -0
  58. package/dist/ui/cajonzero-assets/blobs/CjzpqeDMGwTW4rwJnDVa7L_-ZMPXB83GZIDbDY7cWCM +0 -0
  59. package/dist/ui/cajonzero-assets/blobs/DJB3mDs16RuGcdOKCCjMMXwyI6p5lZrbgPjY_L6Uk7Q +0 -0
  60. package/dist/ui/cajonzero-assets/blobs/DtP529xgwDaffRCOkb2XVsG6HqkPHlbcrklgpT-As_8 +0 -0
  61. package/dist/ui/cajonzero-assets/blobs/Ehfy317KJDTCmpuXWLRcS5Ljl7CvRBnVCE4S-nr8O0M +0 -0
  62. package/dist/ui/cajonzero-assets/blobs/F4c5IJb4dFkgAUxJ0r7Jw_U3u-k7MrpFcpkKSle-P2k +0 -0
  63. package/dist/ui/cajonzero-assets/blobs/FTlABwbChFrePJf9WWAYf1tVorJpT9qdgAfS0xQtxdM +0 -0
  64. package/dist/ui/cajonzero-assets/blobs/FXWQtkvKoY33JwIpKVbPNlKs542KIEbQ4INP6VknKTE +0 -0
  65. package/dist/ui/cajonzero-assets/blobs/GTuRfQ8lo5UVNwVRkX0pffhoTDLnsj_hdgCl0hFPlxk +0 -0
  66. package/dist/ui/cajonzero-assets/blobs/GnW35Ac04sg4J8H2mKIwAfNbtzNuVHM3TVICOTNx_jQ +0 -0
  67. package/dist/ui/cajonzero-assets/blobs/GzV7zUemaTlJlNSuvN_A38PtKnuihTHjPpc0l5Dx_aU +0 -0
  68. package/dist/ui/cajonzero-assets/blobs/HdmOGRHGe3rUiEAvtIPlU2-ou76v7FLYGIIKIcu_rOs +0 -0
  69. package/dist/ui/cajonzero-assets/blobs/I4_DYrkbGGvsGQoptmNOn5ZVJ_ShkU-105VIJq2eXrc +0 -0
  70. package/dist/ui/cajonzero-assets/blobs/IMPYtbLaJ3KYgGN0RrgUGSy2wrJhfY7DNzfhE96S_WY +0 -0
  71. package/dist/ui/cajonzero-assets/blobs/IxW-SXDozs0JBS_q3CftTLVxGI1O8j63AGTBOFSv3Ck +0 -0
  72. package/dist/ui/cajonzero-assets/blobs/KpmKCcqs55T8Ge4r9qk_v9OaUSiTnb1quPj2RAHY7hU +0 -0
  73. package/dist/ui/cajonzero-assets/blobs/KvktHZAiSMrblY_XLWh_yHCtsfv3jLmqRgt-zGu2HR0 +0 -0
  74. package/dist/ui/cajonzero-assets/blobs/L97ARUcIR9G1_lSv1c8-d_qhr-qB15A3Ew4UJ1FnhAY +0 -0
  75. package/dist/ui/cajonzero-assets/blobs/LDdpinDyYwd0nQBnv1o81bQEZET_IzlYwghWyw6VG7Q +0 -0
  76. package/dist/ui/cajonzero-assets/blobs/LIIiMuy_uWeS45Hy_9Hvk1AihC5wguY2eGlfaMGb38k +0 -0
  77. package/dist/ui/cajonzero-assets/blobs/M5L_6hoJaAVEh2olpp0jlhlE6awG_QCmAMPyuIDjY1c +0 -0
  78. package/dist/ui/cajonzero-assets/blobs/MI21yB2DhnLlllbB8CQJtTaH24CL944CDz-RSe05kqA +0 -0
  79. package/dist/ui/cajonzero-assets/blobs/MKXaSqTVklFqaVL1AmWCzzeOsk-pe6Nc4xU8VwH8Zlk +0 -0
  80. package/dist/ui/cajonzero-assets/blobs/MQtnqyF5NPGjICV8o3LaJkf7bVXmGCfZfcxIIoJ9JSo +0 -0
  81. package/dist/ui/cajonzero-assets/blobs/N79jLwnB0Kzh14itL-F-M2fTm3-hAwATe-6AG_IIG8Y +0 -0
  82. package/dist/ui/cajonzero-assets/blobs/P01aphf0Yi8p9JgmbIM1cnZWdlmdXQ1IchBT0zUt8BY +0 -0
  83. package/dist/ui/cajonzero-assets/blobs/PvWei7AAs5UIWUPoZSq21E1abNJ7CakCZHkqq9JdD50 +0 -0
  84. package/dist/ui/cajonzero-assets/blobs/Px0I6b2Moqpmd_wPzbx7iIdoMo--LYwFs4vOX3DIEzE +0 -0
  85. package/dist/ui/cajonzero-assets/blobs/QkjGc5q5hFFv6nk338copZyNAOkmUxMJoXbOO3o9OFA +0 -0
  86. package/dist/ui/cajonzero-assets/blobs/QmPQknmf2oEh2jqbTmodWmYk5efxh2tUH82G8436NyJrcw +0 -0
  87. package/dist/ui/cajonzero-assets/blobs/QmPXZBKX2AzkpfGzFFwLxT2W5Bx9ZQZf8druHJM9dH24eX +0 -0
  88. package/dist/ui/cajonzero-assets/blobs/QmQNdCWfckFcMqQsPEgzhtogS6RcCxVGXXdVuMc3T6aEop +0 -0
  89. package/dist/ui/cajonzero-assets/blobs/QmQzVFuxXyhr8jq2y9ffB6UT1qrL1Aj2mKtk1ozvzxq7gV +0 -0
  90. package/dist/ui/cajonzero-assets/blobs/QmRxn3YzyYcJqwaup7jNtFgRs8NFqbY32GLDSegjz33Zhb +0 -0
  91. package/dist/ui/cajonzero-assets/blobs/QmS8fXohiXa2hMXa19ZegWMFHt5JKu2cZzyYLSdYRwEF4N +0 -0
  92. package/dist/ui/cajonzero-assets/blobs/QmT2jX7MZToEeK5Xh7NcVMArcPygaggqhdKoV17MBfRrWS +0 -0
  93. package/dist/ui/cajonzero-assets/blobs/QmU5nobMghwRPUpqLEpqdFg44iVRwhwQ31THcaaJzkMCDM +0 -0
  94. package/dist/ui/cajonzero-assets/blobs/QmV3hSe9mPsHZ33wqeAg8P3xcHfNgXNyuBW8Z56AoyytNZ +0 -0
  95. package/dist/ui/cajonzero-assets/blobs/QmYC3jWpfvAKMnv34CnhRUjPgZBouaVPySoV7MVMxYgnVG +0 -0
  96. package/dist/ui/cajonzero-assets/blobs/QmYDKCsFcxJ2JnmwaWLL9irVhTh31hEeL96Pd3Z1XL8A4H +0 -0
  97. package/dist/ui/cajonzero-assets/blobs/QmYzvFSBhJ1phKQxHAsT3qq3aJFG1MaKxuRrA43tFXEP1W +1 -0
  98. package/dist/ui/cajonzero-assets/blobs/QmZBk7rEoQJznXRLT81aM8xjj97nwb3fPY5Hp3qAtenqbw +1 -0
  99. package/dist/ui/cajonzero-assets/blobs/QmZhiM1oCKYpR2FdrL9LebRHuAmDPXx6Dn7rhGxjKzKQkk +1 -0
  100. package/dist/ui/cajonzero-assets/blobs/Qmaavi38pp2oU1Ui4WYCAjezGzoDUbk8VPnt2LM2whg1xW +0 -0
  101. package/dist/ui/cajonzero-assets/blobs/Qmbyf9vm2V2qE2GhUq8duNCc9ndPiLmXejkFdNPej3HuEj +0 -0
  102. package/dist/ui/cajonzero-assets/blobs/Qmcaq7qeDrnGD3xZvvAM6qcLKeN7v2mpsK2G5T22fgwWMn +0 -0
  103. package/dist/ui/cajonzero-assets/blobs/QmcuRgtLmk3cZToiCVHHvpgmvo9UV9a9mNry4qcmRh9s7q +0 -0
  104. package/dist/ui/cajonzero-assets/blobs/RD-J5rgF2xqGvZmFOoZT-DW-LMHZh9f8o9a7dgPMUlw +0 -0
  105. package/dist/ui/cajonzero-assets/blobs/RfOhWqMStI91CRsJ_fj1tKZVRgIi1xY9Ct35f49VCjI +0 -0
  106. package/dist/ui/cajonzero-assets/blobs/SQMg9VR2DwDmaNXhA0FfkTNdWoomRqUlZzm7LdEem0o +0 -0
  107. package/dist/ui/cajonzero-assets/blobs/T7ltKgCfHRWDh8DvYWwjTLUm_jyyXGIin8YEQYezqRE +0 -0
  108. package/dist/ui/cajonzero-assets/blobs/Tm6iY1tjlBCxIFVkH6fQ6WSCGItCwgp1qhnV2MSmDAc +0 -0
  109. package/dist/ui/cajonzero-assets/blobs/TygomLARFBxhswYiAEi5onCeMIi6eInfdlt1GTPEzA8 +0 -0
  110. package/dist/ui/cajonzero-assets/blobs/V5w0v22x0_urNk-w77v-F_CTuT_K8ncnQd45-WM_lWM +0 -0
  111. package/dist/ui/cajonzero-assets/blobs/VE8cmDpuiYV41JTNf1-8p6baecUlhPX7BwCuiKjuNN0 +0 -0
  112. package/dist/ui/cajonzero-assets/blobs/Vv6pflLQz9Z06hMF0-3GOPKmEH8ryCECiT6Wnl5tlb8 +0 -0
  113. package/dist/ui/cajonzero-assets/blobs/WnbegyWLVz-LHMQgdlz-Rv3L8knTzkcPxUSGtPegEWE +0 -0
  114. package/dist/ui/cajonzero-assets/blobs/WpRk7YsCv_Ymkrq4efmQOJJMD2pgvveZeiRTXm_ovD4 +0 -0
  115. package/dist/ui/cajonzero-assets/blobs/XmPKwf7XjsDoYuNkjDQrWPzLIu1aTOYnby2bUmQChE4 +0 -0
  116. package/dist/ui/cajonzero-assets/blobs/Xr1Okz2DqOdp07Npx5uH0N3LUScFDdF1hGIPsEBQW3g +0 -0
  117. package/dist/ui/cajonzero-assets/blobs/Y3HX8Arsj45Iuy0qL7woY8qP5QF-W6pbOsNF6oos6zY +0 -0
  118. package/dist/ui/cajonzero-assets/blobs/Ze4mssXcrX1e7z185MAXCZRtMAtwB-zLj1GYyRcMU2c +0 -0
  119. package/dist/ui/cajonzero-assets/blobs/a0b1PSB2YTZGwTGrIhD8RDjboL-_etaKPh9XtBUNXfc +0 -0
  120. package/dist/ui/cajonzero-assets/blobs/aAphssqiPi93r7mAMudYFtFxRuGvLWKyikJifiacQEA +0 -0
  121. package/dist/ui/cajonzero-assets/blobs/an3K4TsulJYxsVVoj8S8kyM4MrGJkz1esWCXafdBu28 +0 -0
  122. package/dist/ui/cajonzero-assets/blobs/b9aYkFSPn7bQXejl_yFahA3JjD33jl2-tn0l0LJ0SIg +0 -0
  123. package/dist/ui/cajonzero-assets/blobs/bV82dxWlxRigqf6FVABNJp5vj9zABVeYHyMlEHwlHN4 +0 -0
  124. package/dist/ui/cajonzero-assets/blobs/bVlJLQq2KPX9d-_pggKAjN1lLNzGcDkAx8Ecd7ZZXtc +0 -0
  125. package/dist/ui/cajonzero-assets/blobs/dFZks4pYaRJ6kU-VDzQv6kIsFhOYZ43-wik950M_x1U +0 -0
  126. package/dist/ui/cajonzero-assets/blobs/e1ZzIyGdOZxAsKAHToSr1Rohek9p9knQoE5r6bssVjQ +0 -0
  127. package/dist/ui/cajonzero-assets/blobs/e4RaMqkk8wRFTc2RbHz6BQkIrjcmYTLnE0IBySs5wFs +0 -0
  128. package/dist/ui/cajonzero-assets/blobs/f3VtPxT0ASkPa5x-e-vX_99ONPxvK_TFPCq_uxrrwb8 +0 -0
  129. package/dist/ui/cajonzero-assets/blobs/f6IcOLssuXmeRXHvfv8HbsBXyUVjQIX1vC1PT0l4ygs +0 -0
  130. package/dist/ui/cajonzero-assets/blobs/fFzXwES0_SIA4gtPnY1rAjJRiZ8PnP7WewMOuDzQRiE +0 -0
  131. package/dist/ui/cajonzero-assets/blobs/fY_KWg63ZqAvBXvX0edrPGD_GevpTGdOeZkcd4ami-8 +0 -0
  132. package/dist/ui/cajonzero-assets/blobs/fw__JzWRTPb8TeUFb0yzX_RAw8HdngVnmkca_GGCwK8 +0 -0
  133. package/dist/ui/cajonzero-assets/blobs/fz8YT7RQVR-jpW4u1ERGHT2GO0AhgkR7nXfypKDLHKQ +0 -0
  134. package/dist/ui/cajonzero-assets/blobs/gHVEVf5jOoe2HepTjoZNvaPkpiFXyI-k-DGn_i7lBik +0 -0
  135. package/dist/ui/cajonzero-assets/blobs/glwjp5nxcyvdUtzLmX3LHoRAtUny01vIlzPyRWlar6U +0 -0
  136. package/dist/ui/cajonzero-assets/blobs/h4Zdd0HdCZR8aOa2FmRmBdxCLwkPDcSXAdEsUAHr0WA +0 -0
  137. package/dist/ui/cajonzero-assets/blobs/hH_d1ycJuEOUg5s2e78mRmVfgDMkmwgCljijPPNJWMw +0 -0
  138. package/dist/ui/cajonzero-assets/blobs/iKKTTHOTy9iBaaozmprN83iLh2W2baZfTXuLu6uaLIw +0 -0
  139. package/dist/ui/cajonzero-assets/blobs/jDW1gLMHdMU77AL4Gpu3OFkm4Z5XOGThqoM-NNx12DY +0 -0
  140. package/dist/ui/cajonzero-assets/blobs/jLETB0_-nLp_xpSomvdz2N82FA067ZjrydzMFDjfhkg +0 -0
  141. package/dist/ui/cajonzero-assets/blobs/j_VxLyyA8FBWp7kHniJSaxTb5A1PsoSRCgLG0Qwz6fY +0 -0
  142. package/dist/ui/cajonzero-assets/blobs/k6DpMny-A1lfQF9IS7s6tr5zdEt1OF8JD_9z-gB8BQk +0 -0
  143. package/dist/ui/cajonzero-assets/blobs/kO9_IinZ9d4EY2FmTEX6oMv2EN-sT8Xq8dcrUWt8nHA +0 -0
  144. package/dist/ui/cajonzero-assets/blobs/l2Z50N8XgMp2foRaY-qCcDoJWe-xd8W2Nztv6A4mxp0 +0 -0
  145. package/dist/ui/cajonzero-assets/blobs/lTD6g8p4M9v6m8li59Kmmunz2L-57QYc7zPFDZ-W-Es +0 -0
  146. package/dist/ui/cajonzero-assets/blobs/mG9tCWEoogpQXIYE8nxwLE8c_VOcFuO_XgnaldjJQ60 +0 -0
  147. package/dist/ui/cajonzero-assets/blobs/n1sBpQmApVlGP4i5qo5KJtx54zUpQsge54pcNzo-MDE +0 -0
  148. package/dist/ui/cajonzero-assets/blobs/nfL8PKk7NDrnhqTH1YMqdx_3KAzzeRfhVu9K5old5ZM +0 -0
  149. package/dist/ui/cajonzero-assets/blobs/nmKC5PJeNwzmF-Idb-Jl6Iuee4aCzwAFm50SjZOB8J0 +1 -0
  150. package/dist/ui/cajonzero-assets/blobs/ntt0GRn7ynGaqPL4sJqRls9E0GQaxE6IYLyw_qp-B9Q +0 -0
  151. package/dist/ui/cajonzero-assets/blobs/o0yyYt7q1aPpjzws0fy35amGvo_KZPHEnbTfUShpx3U +0 -0
  152. package/dist/ui/cajonzero-assets/blobs/oQQX0yM43YWL1vera6TSHhZthZgMnXNhIrGipFvG6No +0 -0
  153. package/dist/ui/cajonzero-assets/blobs/oShx_uIQ-4YZKR6uoZRYHL0lMeSyN1nSJfaAaSP2MiI +1 -0
  154. package/dist/ui/cajonzero-assets/blobs/owSnNxCwon5FLARj6_vN93kAouq8LDotGEwNFqRx92s +0 -0
  155. package/dist/ui/cajonzero-assets/blobs/p0hlunSNmKVR7psYDbGVbl2g55I_GklMquQVTtw_Hng +0 -0
  156. package/dist/ui/cajonzero-assets/blobs/p6ltFaLV93PxC96Tfnpcsd0vZezteR3krx7rTlvhNmQ +0 -0
  157. package/dist/ui/cajonzero-assets/blobs/paRPXEE1Gj4n2JnW1d-qQAAECA9fmA6rWwX6cx5XFhE +0 -0
  158. package/dist/ui/cajonzero-assets/blobs/qFAdwDi7V1l1dyrzd38MX7ncFpbDXCPnrp3-ojx7uiw +0 -0
  159. package/dist/ui/cajonzero-assets/blobs/qNXdY_ukcevLHz6PfB4YebcVKm5ymKkc4RmmNACt58U +1 -0
  160. package/dist/ui/cajonzero-assets/blobs/qkONdDiirNiCzAweq2r9YmPTM6sJo0kFnrzk-_6gpHc +0 -0
  161. package/dist/ui/cajonzero-assets/blobs/rE7gZfK-ViZf-NNWbddA9GiL8jqhZ5BZv5s6PlgoEEc +0 -0
  162. package/dist/ui/cajonzero-assets/blobs/rkXRGaG-CfvGeVCpnVMywGTvb-DH8H2YqpVJWSKXhdw +0 -0
  163. package/dist/ui/cajonzero-assets/blobs/sOgyrN2KX2usg51tbNNxBFrJ9iPPW0CKN91A9za09Tk +0 -0
  164. package/dist/ui/cajonzero-assets/blobs/tAHLZ9uvlsTjN5iAeXczO381B2OSNJ69O95M2YYfcN8 +0 -0
  165. package/dist/ui/cajonzero-assets/blobs/tsr6R4oV7j6XmTitibKMLHwONeTKJ-SZcP9pnBv4Ubk +0 -0
  166. package/dist/ui/cajonzero-assets/blobs/vS95Ll6sl63_jDkyvfifk2BTVyB5WOqjStVP_QYb_Go +0 -0
  167. package/dist/ui/cajonzero-assets/blobs/vlGDb_MDYEWqVbJgC3-f3A_SWm6JuN3ZTBKlmwoDW-o +0 -0
  168. package/dist/ui/cajonzero-assets/blobs/xfFBUN4QqGjaz3Jk20X5tqGfVP0n5pWFhCisMvNKcZw +0 -0
  169. package/dist/ui/cajonzero-assets/blobs/xiNu5A-wieB-673yUKGMq18e_Wty7auBZ5fkArWD-u4 +0 -0
  170. package/dist/ui/cajonzero-assets/blobs/xyo3QwTg87Hhx0oWLkGYnrY_gDqFDPgEXhjxweay1-k +0 -0
  171. package/dist/ui/cajonzero-assets/blobs/xyoDpJvOfUDsOythWBxubACAeEpJBFU6X4gD6UtWDcI +0 -0
  172. package/dist/ui/cajonzero-assets/blobs/y2jNDEAVWMql33MI7A9MetZoMzoYZ3OQkfpE_ttnZpA +0 -0
  173. package/dist/ui/cajonzero-assets/blobs/yP1TmmOwXInzjarE0CKhGb0wrgyP8mb6cBDktdlxSIU +0 -0
  174. package/dist/ui/cajonzero-assets/blobs/z7PzcCMU5mgfNHEC1sglsERnwrO5r_eMXeR6zSN78Os +0 -0
  175. package/dist/ui/cajonzero-assets/blobs/zBd-L4rx5mRaCLXMVzf1YNsKFxhABcx9AXlw8uEmpq8 +0 -0
  176. package/dist/ui/cajonzero-assets/blobs/zr-Gim06sJj1VyQIdDh1Kp0j8A4gfKoRjsQTHGdgcZQ +0 -0
  177. package/dist/ui/index.html +14 -0
  178. package/dist/ui/skins/chinese-doll.png +0 -0
  179. package/dist/ui/skins/christmas-girl.png +0 -0
  180. package/dist/ui/skins/cowboy.png +0 -0
  181. package/dist/ui/skins/explorer.png +0 -0
  182. package/dist/ui/skins/little-prince.png +0 -0
  183. package/dist/ui/skins/maid.png +0 -0
  184. package/dist/ui/skins/pilot.png +0 -0
  185. package/dist/ui/skins/pink-girl.png +0 -0
  186. package/package.json +94 -6
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Toby Lai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,74 @@
1
- # Temporary Holding Version
1
+ # cajonzero
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Serverless(Cloudflare)的 BOX3 **仅 Play 端**引擎:内置账号系统,房间跑在
4
+ Durable Object 上,地图放在 OSS/CDN。
5
+
6
+ ## 安装
7
+
8
+ ```bash
9
+ npm install cajonzero
10
+ npx cj0 --help
11
+ ```
12
+
13
+ ## 本地运行
14
+
15
+ ```bash
16
+ npm install
17
+ npm run build # 构建大厅/后台
18
+ npm run demo # http://127.0.0.1:8787
19
+ ```
20
+
21
+ 打开页面后注册账号、选一张地图即可进入房间。
22
+ 管理后台在 `/admin/login`,演示令牌为 `cajonzero-demo-admin-token`。
23
+
24
+ ## 创建自己的服务
25
+
26
+ ```bash
27
+ cj0 create my-server
28
+ cd my-server
29
+ npm install
30
+ npm run dev # 本地预览
31
+ ```
32
+
33
+ 部署前配置三项:
34
+
35
+ ```bash
36
+ npx wrangler kv namespace create CAJONZERO_KV # 把返回的 id 填进 wrangler.jsonc
37
+ npx wrangler secret put CAJONZERO_SESSION_SECRET # 会话签名密钥
38
+ npx wrangler secret put BOX_PLAY_ADMIN_TOKEN # 管理后台令牌
39
+ npm run deploy
40
+ ```
41
+
42
+ ## 配置地图
43
+
44
+ 地图不随 worker 上传。把解包后的 `.boxplay` 目录传到 OSS/S3/CDN,
45
+ 再在 `cajonzero/maps.json` 中登记:
46
+
47
+ ```json
48
+ {
49
+ "version": 1,
50
+ "maps": [
51
+ {
52
+ "slug": "race",
53
+ "root": "https://<你的 CDN>/box3/race/",
54
+ "worldId": "<世界 id>",
55
+ "name": "显示名",
56
+ "etag": "v1"
57
+ }
58
+ ]
59
+ }
60
+ ```
61
+
62
+ 地图内容更新时记得提升 `etag`(否则会命中 KV 里的旧缓存)。
63
+ 房间参数、地图拉取策略等在 `cajonzero/config.json` 中调整。
64
+
65
+ ## 常用命令
66
+
67
+ ```bash
68
+ cj0 serve [--port <port>] [--host <host>] # 本地启动
69
+ cj0 create <folder> # 生成部署项目
70
+ npm test # 运行测试
71
+ npm run ci:gates # 完整检查(类型/测试/构建)
72
+ ```
73
+
74
+ 更多细节见 [`docs/`](./docs/) 与 [`demo/`](./demo/README.md)。
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1,477 @@
1
+ #!/usr/bin/env node
2
+ import { mkdirSync, existsSync, statSync, writeFileSync, readdirSync, readFileSync } from 'fs';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ // src/scaffold/templates.ts
7
+ var SCAFFOLD_ENTRY_PATH = "src/index.ts";
8
+ var SCAFFOLD_COMPATIBILITY_DATE = "2026-09-01";
9
+ var SCAFFOLD_KV_PLACEHOLDER_ID = "PLACEHOLDER_KV_ID";
10
+ var SCAFFOLD_ENTRY_CONTENT = [
11
+ 'import config from "../cajonzero/config.json";',
12
+ 'import maps from "../cajonzero/maps.json";',
13
+ "",
14
+ 'import { serve } from "cajonzero/serve";',
15
+ "",
16
+ "export default serve({ config, maps });",
17
+ 'export { Room } from "cajonzero";',
18
+ ""
19
+ ].join("\n");
20
+ var SCAFFOLD_CONFIG_CONTENT = `${JSON.stringify(
21
+ {
22
+ name: "<project-name>",
23
+ admin: { path: "/admin" },
24
+ room: { tickRate: 64, emptyGraceMs: 48e4 },
25
+ maps: {
26
+ cacheTtlSeconds: 86400,
27
+ maxDownloadBytes: 33554432,
28
+ concurrency: 8,
29
+ requestTimeoutMs: 15e3
30
+ }
31
+ },
32
+ null,
33
+ 2
34
+ )}
35
+ `;
36
+ var SCAFFOLD_MAPS_CONTENT = `${JSON.stringify({ version: 1, maps: [] }, null, 2)}
37
+ `;
38
+ var SHIP_UI_SCRIPT = `node -e "const fs=require('node:fs'),p=require('node:path');fs.cpSync(p.join(p.dirname(require.resolve('cajonzero/package.json')),'dist','ui'),p.join('dist','ui'),{recursive:true,force:true})"`;
39
+ function packageJson(options) {
40
+ const manifest = {
41
+ name: options.packageName,
42
+ version: "0.0.0",
43
+ private: true,
44
+ type: "module",
45
+ scripts: {
46
+ dev: `${SHIP_UI_SCRIPT} && wrangler dev`,
47
+ build: `${SHIP_UI_SCRIPT} && wrangler deploy --dry-run`,
48
+ deploy: `${SHIP_UI_SCRIPT} && wrangler deploy`,
49
+ // `prepare` also runs after `npm install`, so a plain install leaves a
50
+ // ready-to-deploy project.
51
+ prepare: SHIP_UI_SCRIPT
52
+ },
53
+ dependencies: {
54
+ cajonzero: options.cajonzeroRange,
55
+ unstorage: options.unstorageRange
56
+ },
57
+ devDependencies: {
58
+ wrangler: options.wranglerRange
59
+ }
60
+ };
61
+ return `${JSON.stringify(manifest, null, 2)}
62
+ `;
63
+ }
64
+ function wranglerConfig(options) {
65
+ return [
66
+ "{",
67
+ " // cajonzero-created project \u2014 Cloudflare Workers config.",
68
+ " // `main` is the thin worker entry; wrangler bundles it (and cajonzero) on",
69
+ " // the fly, so there is no separate worker build step.",
70
+ ' "$schema": "./node_modules/wrangler/config-schema.json",',
71
+ ` "name": ${JSON.stringify(options.packageName)},`,
72
+ ` "main": ${JSON.stringify(SCAFFOLD_ENTRY_PATH)},`,
73
+ ` "compatibility_date": ${JSON.stringify(options.compatibilityDate)},`,
74
+ " // Deliberately NO `nodejs_compat`: cajonzero's worker path is Node-free.",
75
+ ' "compatibility_flags": [],',
76
+ " // Static UI (play lobby + owner admin console) served by the worker.",
77
+ " // cajonzero ships the built assets into this directory.",
78
+ ' "assets": {',
79
+ ' "directory": "dist/ui",',
80
+ " // History routing: deep links (/play/x, /admin/bans) boot index.html.",
81
+ ' "not_found_handling": "single-page-application",',
82
+ ' "run_worker_first": ["/api/*", "/runtime/*"]',
83
+ " },",
84
+ " // Non-secret deployment label. Secrets are set with `wrangler secret put`:",
85
+ " // CAJONZERO_SESSION_SECRET, BOX_PLAY_ADMIN_TOKEN",
86
+ ' "vars": {',
87
+ ' "CAJONZERO_ENV": "development"',
88
+ " },",
89
+ ' "kv_namespaces": [',
90
+ " {",
91
+ " // Player/account data + map-script KV + resolved map-seed cache.",
92
+ ' "binding": "CAJONZERO_KV",',
93
+ " // Replace with `wrangler kv namespace create CAJONZERO_KV` output.",
94
+ ` "id": ${JSON.stringify(SCAFFOLD_KV_PLACEHOLDER_ID)}`,
95
+ " }",
96
+ " ],",
97
+ ' "durable_objects": {',
98
+ ' "bindings": [',
99
+ " {",
100
+ " // Per-room actor namespace. `Room` is re-exported by the entry.",
101
+ ' "name": "ROOMS",',
102
+ ' "class_name": "Room"',
103
+ " }",
104
+ " ]",
105
+ " },",
106
+ ' "migrations": [',
107
+ " {",
108
+ ' "tag": "v1",',
109
+ ' "new_sqlite_classes": ["Room"]',
110
+ " }",
111
+ " ]",
112
+ "}",
113
+ ""
114
+ ].join("\n");
115
+ }
116
+ function gitignore() {
117
+ return ["node_modules", "dist", ".wrangler", ".dev.vars", ""].join("\n");
118
+ }
119
+ function readme(options) {
120
+ return [
121
+ `# ${options.packageName}`,
122
+ "",
123
+ "A serverless (Cloudflare Workers) BOX3 **play** server, scaffolded by",
124
+ "[`cajonzero`](https://www.npmjs.com/package/cajonzero).",
125
+ "",
126
+ "This project contains **no engine source code** \u2014 configuration plus a short",
127
+ "worker entry that hands `cajonzero/config.json` and `cajonzero/maps.json` to the",
128
+ "runtime:",
129
+ "",
130
+ "```ts",
131
+ 'import config from "../cajonzero/config.json";',
132
+ 'import maps from "../cajonzero/maps.json";',
133
+ 'import { serve } from "cajonzero/serve";',
134
+ "",
135
+ "export default serve({ config, maps });",
136
+ 'export { Room } from "cajonzero";',
137
+ "```",
138
+ "",
139
+ "## Quick start",
140
+ "",
141
+ "```bash",
142
+ "npm install # also syncs cajonzero's prebuilt lobby/console into dist/ui",
143
+ "npm run dev # wrangler dev \u2192 http://localhost:8787",
144
+ "```",
145
+ "",
146
+ "`npm run build` validates the deploy by bundling the worker without",
147
+ "publishing (`wrangler deploy --dry-run`).",
148
+ "",
149
+ "## Required secrets",
150
+ "",
151
+ "Set both secrets with Wrangler (never commit them):",
152
+ "",
153
+ "```bash",
154
+ "npx wrangler secret put CAJONZERO_SESSION_SECRET # signs player session proofs",
155
+ "npx wrangler secret put BOX_PLAY_ADMIN_TOKEN # owner token for the admin API",
156
+ "```",
157
+ "",
158
+ "## Maps (object storage)",
159
+ "",
160
+ "Maps are **not** uploaded with the worker and are never unpacked at runtime.",
161
+ "Unpack the `.boxplay` yourself and upload the resulting directory to OSS/S3/CDN",
162
+ "with the archive layout preserved:",
163
+ "",
164
+ "```text",
165
+ "<root>/bundle.json",
166
+ "<root>/worlds/<worldId>/manifest.json",
167
+ "<root>/worlds/<worldId>/data/project-state.json",
168
+ "<root>/worlds/<worldId>/data/blobs/<cid>",
169
+ "```",
170
+ "",
171
+ "Then add an entry to `cajonzero/maps.json`:",
172
+ "",
173
+ "```json",
174
+ "{",
175
+ ' "version": 1,',
176
+ ' "maps": [',
177
+ " {",
178
+ ' "slug": "omega",',
179
+ ' "root": "https://cdn.example.com/cajonzero/omega/",',
180
+ ' "worldId": "project-omega",',
181
+ ' "name": "Omega City Reloaded",',
182
+ ' "version": "1.0.4",',
183
+ ' "etag": "v1.0.4"',
184
+ " }",
185
+ " ]",
186
+ "}",
187
+ "```",
188
+ "",
189
+ "- `root` must be the unpacked map directory and end with `/`.",
190
+ "- `etag` (or `version`) is the seed-cache revision: bump it whenever you",
191
+ " re-upload the map, otherwise the cached world stays stale.",
192
+ "- The bucket may be public-read; the server fetches it, so no CORS is needed",
193
+ " for gameplay. Enable CORS only if the browser loads assets from it.",
194
+ "",
195
+ "## Where things live",
196
+ "",
197
+ "- **Play lobby** \u2014 the worker serves the lobby at `/`.",
198
+ "- **Admin console** \u2014 at `/admin` (sign in with `BOX_PLAY_ADMIN_TOKEN`) for",
199
+ " player bans and runtime settings; its JSON API is under `/api/admin/*`.",
200
+ "- **Map catalog** \u2014 `GET /api/maps` returns the entries from `maps.json`.",
201
+ "",
202
+ "## Deploy",
203
+ "",
204
+ "```bash",
205
+ "npm run deploy # wrangler deploy",
206
+ "```",
207
+ ""
208
+ ].join("\n");
209
+ }
210
+ function buildScaffoldFiles(options) {
211
+ return [
212
+ { path: "package.json", content: packageJson(options) },
213
+ { path: "wrangler.jsonc", content: wranglerConfig(options) },
214
+ { path: SCAFFOLD_ENTRY_PATH, content: SCAFFOLD_ENTRY_CONTENT },
215
+ {
216
+ path: "cajonzero/config.json",
217
+ content: SCAFFOLD_CONFIG_CONTENT.replace("<project-name>", options.packageName)
218
+ },
219
+ { path: "cajonzero/maps.json", content: SCAFFOLD_MAPS_CONTENT },
220
+ { path: ".gitignore", content: gitignore() },
221
+ { path: "README.md", content: readme(options) }
222
+ ];
223
+ }
224
+ var CAJONZERO_RANGE_PREFIX = "^";
225
+ var FALLBACK_WRANGLER_RANGE = "^4.151.1";
226
+ var FALLBACK_UNSTORAGE_RANGE = "^1.17.6";
227
+ var PACKAGE_JSON_URL = new URL("../../package.json", import.meta.url);
228
+ var ScaffoldError = class extends Error {
229
+ code;
230
+ constructor(code, message) {
231
+ super(message);
232
+ this.name = "ScaffoldError";
233
+ this.code = code;
234
+ }
235
+ };
236
+ function readCajonzeroPackage(manifestPath) {
237
+ const filePath = fileURLToPath(PACKAGE_JSON_URL);
238
+ const raw = readFileSync(filePath, "utf8");
239
+ const parsed = JSON.parse(raw);
240
+ const version = typeof parsed.version === "string" && parsed.version.length > 0 ? parsed.version : "0.0.0";
241
+ const wrangler = parsed.devDependencies?.["wrangler"];
242
+ const wranglerRange = typeof wrangler === "string" && wrangler.length > 0 ? wrangler : FALLBACK_WRANGLER_RANGE;
243
+ const unstorage = parsed.dependencies?.["unstorage"];
244
+ const unstorageRange = typeof unstorage === "string" && unstorage.length > 0 ? unstorage : FALLBACK_UNSTORAGE_RANGE;
245
+ return { version, wranglerRange, unstorageRange };
246
+ }
247
+ function toPackageName(folder) {
248
+ const base = path.basename(folder);
249
+ const slug = base.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[-._]+/, "").replace(/[-._]+$/, "");
250
+ return slug.length > 0 ? slug : "cajonzero-app";
251
+ }
252
+ function isNonEmptyDirectory(dir) {
253
+ if (!existsSync(dir)) return false;
254
+ if (!statSync(dir).isDirectory()) return false;
255
+ return readdirSync(dir).length > 0;
256
+ }
257
+ function createProject(folder, options = {}) {
258
+ const name = typeof folder === "string" ? folder.trim() : "";
259
+ if (name.length === 0) {
260
+ throw new ScaffoldError("INVALID_TARGET", "create requires a target folder");
261
+ }
262
+ const cwd = options.cwd ?? process.cwd();
263
+ const target = path.resolve(cwd, name);
264
+ if (existsSync(target) && !statSync(target).isDirectory()) {
265
+ throw new ScaffoldError("INVALID_TARGET", `target exists and is not a directory: ${target}`);
266
+ }
267
+ if (isNonEmptyDirectory(target)) {
268
+ throw new ScaffoldError(
269
+ "TARGET_NOT_EMPTY",
270
+ `target directory already exists and is not empty: ${target} (refusing to overwrite)`
271
+ );
272
+ }
273
+ const manifest = options.version !== void 0 ? void 0 : readCajonzeroPackage();
274
+ const version = options.version ?? manifest?.version ?? "0.0.0";
275
+ const wranglerRange = options.wranglerRange ?? manifest?.wranglerRange ?? FALLBACK_WRANGLER_RANGE;
276
+ const unstorageRange = options.unstorageRange ?? manifest?.unstorageRange ?? FALLBACK_UNSTORAGE_RANGE;
277
+ const files = buildScaffoldFiles({
278
+ packageName: toPackageName(target),
279
+ cajonzeroRange: `${CAJONZERO_RANGE_PREFIX}${version}`,
280
+ unstorageRange,
281
+ wranglerRange,
282
+ compatibilityDate: options.compatibilityDate ?? SCAFFOLD_COMPATIBILITY_DATE
283
+ });
284
+ mkdirSync(target, { recursive: true });
285
+ for (const file of files) {
286
+ const fullPath = path.join(target, file.path);
287
+ mkdirSync(path.dirname(fullPath), { recursive: true });
288
+ writeFileSync(fullPath, file.content, "utf8");
289
+ }
290
+ return { target, files: files.map((file) => file.path) };
291
+ }
292
+
293
+ // src/bin/cj0.ts
294
+ var USAGE = `cj0 \u2014 serverless (Cloudflare) play-only BOX3 engine
295
+
296
+ Usage:
297
+ cj0 <command> [options]
298
+
299
+ Commands:
300
+ create <folder> Scaffold a deployable project
301
+ serve [--port <port>] [--host <host>] Run the cajonzero server locally (workerd)
302
+
303
+ Serve options:
304
+ --port <port> Listener port (default: 8787)
305
+ --host <host> Listener host (default: 127.0.0.1)
306
+ --config <file> Wrangler config (default: wrangler.jsonc)
307
+ -h, --help Show this help
308
+
309
+ Maps: unpack the .boxplay, upload the directory to OSS/CDN, and list its root
310
+ in cajonzero/maps.json. The CLI does not import map archives.
311
+ `;
312
+ var DEFAULT_SERVE_PORT = 8787;
313
+ var DEFAULT_SERVE_HOST = "127.0.0.1";
314
+ var DEFAULT_CONFIG = "wrangler.jsonc";
315
+ var LOCAL_DEV_SECRETS = ["CAJONZERO_SESSION_SECRET", "BOX_PLAY_ADMIN_TOKEN"];
316
+ function localDevVars() {
317
+ const vars = {};
318
+ for (const name of LOCAL_DEV_SECRETS) {
319
+ const value = process.env[name];
320
+ if (value !== void 0 && value.length > 0) {
321
+ vars[name] = value;
322
+ }
323
+ }
324
+ return Object.keys(vars).length > 0 ? vars : void 0;
325
+ }
326
+ function printUsage() {
327
+ process.stdout.write(USAGE);
328
+ }
329
+ function fail(message) {
330
+ process.stderr.write(`cajonzero: ${message}
331
+ `);
332
+ process.exitCode = 1;
333
+ }
334
+ function errorLabel(error) {
335
+ if (error instanceof ScaffoldError) {
336
+ return `${error.code}: ${error.message}`;
337
+ }
338
+ return error instanceof Error ? error.message : String(error);
339
+ }
340
+ function runCreate(args) {
341
+ const [folder] = args;
342
+ if (folder === void 0) {
343
+ fail("create requires: cj0 create <folder>");
344
+ return;
345
+ }
346
+ const result = createProject(folder);
347
+ process.stdout.write(
348
+ `created project in ${result.target} (${result.files.length} files)
349
+ ${result.files.join(", ")}
350
+ next: cd ${folder} && npm install && npm run dev
351
+ `
352
+ );
353
+ }
354
+ function readFlagValue(args, index, flag) {
355
+ const inline = args[index];
356
+ if (inline !== void 0 && inline.startsWith(`${flag}=`)) {
357
+ return inline.slice(flag.length + 1);
358
+ }
359
+ const value = args[index + 1];
360
+ if (value === void 0 || value.startsWith("-")) {
361
+ throw new Error(`${flag} requires a value`);
362
+ }
363
+ return value;
364
+ }
365
+ function parseServeFlags(args) {
366
+ let port = DEFAULT_SERVE_PORT;
367
+ let host = DEFAULT_SERVE_HOST;
368
+ let config = DEFAULT_CONFIG;
369
+ for (let i = 0; i < args.length; i += 1) {
370
+ const arg = args[i];
371
+ if (arg === void 0) continue;
372
+ if (arg === "--port" || arg.startsWith("--port=")) {
373
+ const raw = readFlagValue(args, i, "--port");
374
+ const parsed = Number(raw);
375
+ if (!Number.isInteger(parsed) || parsed < 0 || parsed > 65535) {
376
+ throw new Error(`--port must be an integer in [0, 65535] (got "${raw}")`);
377
+ }
378
+ port = parsed;
379
+ if (!arg.includes("=")) i += 1;
380
+ } else if (arg === "--host" || arg.startsWith("--host=")) {
381
+ host = readFlagValue(args, i, "--host");
382
+ if (!arg.includes("=")) i += 1;
383
+ } else if (arg === "--config" || arg.startsWith("--config=")) {
384
+ config = readFlagValue(args, i, "--config");
385
+ if (!arg.includes("=")) i += 1;
386
+ } else {
387
+ throw new Error(`unexpected serve option "${arg}"`);
388
+ }
389
+ }
390
+ return { port, host, config };
391
+ }
392
+ async function runServe(args) {
393
+ const flags = parseServeFlags(args);
394
+ const { unstable_dev, unstable_readConfig } = await import('wrangler');
395
+ const config = unstable_readConfig({ config: flags.config });
396
+ const entry = config.main;
397
+ if (entry === void 0 || entry.length === 0) {
398
+ throw new Error(`no worker entry ("main") found in ${flags.config}`);
399
+ }
400
+ const assetsDir = config.assets?.directory;
401
+ if (typeof assetsDir === "string" && assetsDir.length > 0) {
402
+ const configDir = path.dirname(path.resolve(process.cwd(), flags.config));
403
+ mkdirSync(path.resolve(configDir, assetsDir), { recursive: true });
404
+ }
405
+ const secrets = localDevVars();
406
+ const worker = await unstable_dev(entry, {
407
+ config: flags.config,
408
+ ip: flags.host,
409
+ port: flags.port,
410
+ local: true,
411
+ logLevel: "info",
412
+ // Inject local-dev secrets (from the environment) on top of the config
413
+ // `vars` so auth/session work locally without `wrangler secret put`.
414
+ ...secrets !== void 0 ? { vars: { ...config.vars ?? {}, ...secrets } } : {},
415
+ experimental: {
416
+ disableExperimentalWarning: true,
417
+ disableDevRegistry: true,
418
+ showInteractiveDevSession: false
419
+ }
420
+ });
421
+ process.stdout.write(
422
+ `cj0 serve listening on http://${worker.address}:${worker.port}
423
+ (workerd via wrangler dev \xB7 config ${flags.config} \xB7 DO/KV/assets bound)
424
+ ` + (secrets !== void 0 ? ` (local dev secrets injected: ${Object.keys(secrets).join(", ")})
425
+ ` : "")
426
+ );
427
+ let stopping = false;
428
+ const shutdown = async (signal) => {
429
+ if (stopping) return;
430
+ stopping = true;
431
+ process.stdout.write(`
432
+ cajonzero: received ${signal}, shutting down
433
+ `);
434
+ try {
435
+ await worker.stop();
436
+ } finally {
437
+ process.exit(0);
438
+ }
439
+ };
440
+ process.on("SIGINT", () => {
441
+ void shutdown("SIGINT");
442
+ });
443
+ process.on("SIGTERM", () => {
444
+ void shutdown("SIGTERM");
445
+ });
446
+ await worker.waitUntilExit();
447
+ }
448
+ async function main(argv) {
449
+ const [command, ...rest] = argv;
450
+ if (command === void 0 || command === "--help" || command === "-h" || command === "help") {
451
+ printUsage();
452
+ return;
453
+ }
454
+ try {
455
+ switch (command) {
456
+ case "serve":
457
+ await runServe(rest);
458
+ return;
459
+ case "create":
460
+ runCreate(rest);
461
+ return;
462
+ default:
463
+ process.stderr.write(`cajonzero: unknown command "${command}"
464
+
465
+ `);
466
+ printUsage();
467
+ process.exitCode = 1;
468
+ }
469
+ } catch (error) {
470
+ fail(errorLabel(error));
471
+ }
472
+ }
473
+ main(process.argv.slice(2)).catch((error) => {
474
+ fail(errorLabel(error));
475
+ });
476
+ //# sourceMappingURL=cj0.js.map
477
+ //# sourceMappingURL=cj0.js.map