@underpostnet/cyberia 3.3.0 → 3.3.76

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 (568) hide show
  1. package/.dockerignore +1 -0
  2. package/.env.example +17 -5
  3. package/.github/workflows/coverall.cyberia.ci.yml +39 -14
  4. package/.github/workflows/cyberia-client.cd.yml +5 -0
  5. package/.github/workflows/cyberia-server.cd.yml +5 -0
  6. package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
  7. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
  8. package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
  9. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
  10. package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
  11. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
  12. package/.github/workflows/engine-cyberia.cd.yml +3 -0
  13. package/.github/workflows/engine-cyberia.ci.yml +4 -5
  14. package/.github/workflows/ghpkg.ci.yml +35 -20
  15. package/.github/workflows/hardhat.ci.yml +12 -11
  16. package/.github/workflows/npmpkg.ci.yml +17 -15
  17. package/.github/workflows/publish.cyberia.ci.yml +44 -0
  18. package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
  19. package/.github/workflows/release.cd.yml +1 -0
  20. package/.prettierignore +1 -0
  21. package/AGENTS.md +96 -0
  22. package/CHANGELOG.md +653 -2513
  23. package/CLI-HELP.md +323 -157
  24. package/Dockerfile +25 -9
  25. package/Dockerfile.dev +25 -9
  26. package/Dockerfile.test +5 -5
  27. package/README.md +48 -28
  28. package/bin/build.js +86 -41
  29. package/bin/build.template.js +8 -3
  30. package/bin/cyberia.js +1494 -1403
  31. package/bin/deploy.js +18 -104
  32. package/bin/index.js +1494 -1403
  33. package/compose.env +17 -5
  34. package/conf.js +98 -7
  35. package/deploy/cyberia-client/deploy.sh +46 -0
  36. package/deploy/cyberia-client/package.sh +17 -0
  37. package/deploy/cyberia-client/state.sh +15 -0
  38. package/deploy/cyberia-server/deploy.sh +46 -0
  39. package/deploy/cyberia-server/package.sh +17 -0
  40. package/deploy/cyberia-server/state.sh +15 -0
  41. package/deploy/dd-cyberia/deploy.sh +9 -29
  42. package/deploy/dd-cyberia/init.sh +38 -45
  43. package/deploy/dd-cyberia/package.sh +16 -0
  44. package/deploy/dd-cyberia/state.sh +14 -0
  45. package/deploy/dd-cyberia/sync-deploy.sh +133 -147
  46. package/deploy/lib/config.sh +29 -0
  47. package/deploy/lib/github-actions-logging.sh +610 -0
  48. package/deploy/lib/host.sh +194 -0
  49. package/deploy/lib/state.sh +65 -0
  50. package/deploy/pwa-microservices-template/deploy.sh +17 -42
  51. package/deploy/release/deploy.sh +9 -41
  52. package/deployment.yaml +7 -2
  53. package/docker-compose.yml +23 -17
  54. package/examples/static-page/README.md +19 -19
  55. package/examples/static-page/ssr-components/CustomPage.js +2 -2
  56. package/hardhat/hardhat.config.js +1 -6
  57. package/hardhat/package-lock.json +101 -40
  58. package/hardhat/package.json +2 -2
  59. package/manifests/alertmanager/deployment.yaml +81 -0
  60. package/manifests/blackbox-exporter/deployment.yaml +75 -0
  61. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +32 -7
  62. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +32 -7
  63. package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
  64. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  65. package/manifests/deployment/mongo-express/deployment.yaml +46 -27
  66. package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
  67. package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
  68. package/manifests/deployment/mongo-express/service.yaml +16 -0
  69. package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
  70. package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
  71. package/manifests/grafana/deployment.yaml +26 -7
  72. package/manifests/grafana/kustomization.yaml +1 -0
  73. package/manifests/grafana/service.yaml +6 -1
  74. package/manifests/mariadb/pv.yaml +1 -0
  75. package/manifests/mongodb/statefulset.yaml +9 -2
  76. package/manifests/mysql/pv-pvc.yaml +14 -1
  77. package/manifests/postgresql/pv.yaml +12 -1
  78. package/manifests/postgresql/pvc.yaml +1 -0
  79. package/manifests/prometheus/deployment.yaml +18 -22
  80. package/package.json +87 -12
  81. package/scripts/event-monitor.sh +56 -0
  82. package/scripts/k3s-node-setup.sh +27 -14
  83. package/scripts/kubeadm-node-setup.sh +31 -11
  84. package/scripts/maas-setup.sh +8 -8
  85. package/scripts/selinux-normalize.sh +907 -0
  86. package/scripts/shutdown-machine.sh +843 -0
  87. package/scripts/test-monitor.sh +5 -5
  88. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +15 -10
  89. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
  90. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +7 -2
  91. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +90 -186
  92. package/src/api/core/core.controller.js +1 -1
  93. package/src/api/core/core.router.js +2 -2
  94. package/src/api/core/core.service.js +2 -2
  95. package/src/api/crypto/crypto.controller.js +1 -1
  96. package/src/api/crypto/crypto.service.js +1 -1
  97. package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
  98. package/src/api/cyberia-action/cyberia-action.router.js +3 -3
  99. package/src/api/cyberia-action/cyberia-action.service.js +5 -6
  100. package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
  101. package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
  102. package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
  103. package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
  104. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +2 -4
  105. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
  106. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +13 -35
  107. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +17 -34
  108. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
  109. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
  110. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
  111. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
  112. package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
  113. package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
  114. package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
  115. package/src/api/cyberia-entity/cyberia-entity.service.js +3 -3
  116. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
  117. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
  118. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -2
  119. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +468 -5
  120. package/src/api/cyberia-instance/cyberia-fallback-capture.js +502 -0
  121. package/src/api/cyberia-instance/cyberia-fallback-world.js +29 -40
  122. package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
  123. package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
  124. package/src/api/cyberia-instance/cyberia-instance-map.service.js +35 -142
  125. package/src/api/cyberia-instance/cyberia-instance.controller.js +2 -5
  126. package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
  127. package/src/api/cyberia-instance/cyberia-instance.router.js +5 -18
  128. package/src/api/cyberia-instance/cyberia-instance.service.js +5 -45
  129. package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
  130. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
  131. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
  132. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
  133. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +76 -3
  134. package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
  135. package/src/api/cyberia-map/cyberia-map.router.js +1 -1
  136. package/src/api/cyberia-map/cyberia-map.service.js +8 -4
  137. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
  138. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
  139. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
  140. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
  141. package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
  142. package/src/api/cyberia-quest/cyberia-quest.router.js +4 -4
  143. package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
  144. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
  145. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
  146. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
  147. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
  148. package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
  149. package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
  150. package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
  151. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -214
  152. package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
  153. package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
  154. package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
  155. package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
  156. package/src/api/default/default.controller.js +1 -1
  157. package/src/api/default/default.router.js +1 -1
  158. package/src/api/default/default.service.js +2 -2
  159. package/src/api/document/document.controller.js +1 -1
  160. package/src/api/document/document.router.js +1 -1
  161. package/src/api/document/document.service.js +2 -2
  162. package/src/api/file/file.controller.js +1 -1
  163. package/src/api/file/file.ref.js +153 -0
  164. package/src/api/file/file.ref.json +11 -2
  165. package/src/api/file/file.router.js +1 -1
  166. package/src/api/file/file.service.js +2 -2
  167. package/src/api/instance/instance.controller.js +1 -1
  168. package/src/api/instance/instance.router.js +1 -1
  169. package/src/api/instance/instance.service.js +2 -2
  170. package/src/api/ipfs/ipfs.controller.js +1 -1
  171. package/src/api/ipfs/ipfs.router.js +2 -2
  172. package/src/api/ipfs/ipfs.service.js +2 -2
  173. package/src/api/object-layer/object-layer.controller.js +1 -1
  174. package/src/api/object-layer/object-layer.model.js +47 -12
  175. package/src/api/object-layer/object-layer.router.js +12 -5
  176. package/src/api/object-layer/object-layer.service.js +116 -123
  177. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
  178. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
  179. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
  180. package/src/api/test/test.controller.js +1 -1
  181. package/src/api/test/test.service.js +1 -1
  182. package/src/api/user/guest.service.js +3 -3
  183. package/src/api/user/user.controller.js +1 -1
  184. package/src/api/user/user.router.js +2 -2
  185. package/src/api/user/user.service.js +4 -4
  186. package/src/api.js +5 -9
  187. package/src/cli/app.js +402 -0
  188. package/src/cli/baremetal.js +30 -35
  189. package/src/cli/client.js +306 -0
  190. package/src/cli/cloud-init.js +3 -3
  191. package/src/cli/cluster.js +191 -82
  192. package/src/cli/db.js +120 -68
  193. package/src/cli/deploy.js +157 -75
  194. package/src/cli/docker-compose.js +5 -5
  195. package/src/cli/domains.js +184 -0
  196. package/src/cli/dotenv-store.js +143 -0
  197. package/src/cli/event.js +2281 -0
  198. package/src/cli/fs-selection.js +115 -0
  199. package/src/cli/fs.js +159 -343
  200. package/src/cli/host.js +672 -0
  201. package/src/cli/image.js +4 -6
  202. package/src/cli/index.js +343 -151
  203. package/src/cli/ipfs.js +34 -30
  204. package/src/cli/kickstart.js +1 -1
  205. package/src/cli/kubectl.js +218 -41
  206. package/src/cli/lxd.js +3 -3
  207. package/src/cli/monitor.js +1359 -26
  208. package/src/cli/package.js +90 -0
  209. package/src/cli/release.js +16 -12
  210. package/src/cli/repository.js +586 -363
  211. package/src/cli/run.js +398 -843
  212. package/src/cli/secrets.js +2158 -964
  213. package/src/cli/ssh.js +478 -279
  214. package/src/cli/state.js +394 -0
  215. package/src/cli/static.js +2 -2
  216. package/src/cli/system.js +1 -1
  217. package/src/cli/test.js +203 -125
  218. package/src/cli/vultr.js +61 -21
  219. package/src/cli/wireguard.js +1112 -306
  220. package/src/client/components/core/CalendarCore.js +53 -96
  221. package/src/client/components/core/Docs.js +327 -303
  222. package/src/client/components/core/FileExplorer.js +0 -21
  223. package/src/client/components/core/Modal.js +56 -1
  224. package/src/client/components/core/PanelForm.js +4 -4
  225. package/src/client/components/core/Repository.js +56 -0
  226. package/src/client/components/core/Translate.js +7 -0
  227. package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
  228. package/src/client/components/core/Wallet.js +0 -11
  229. package/src/client/components/core/Worker.js +7 -1
  230. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
  231. package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
  232. package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
  233. package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
  234. package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
  235. package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
  236. package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
  237. package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
  238. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
  239. package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
  240. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +2 -35
  241. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
  242. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
  243. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
  244. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
  245. package/src/client/components/default/AppShellDefault.js +1 -1
  246. package/src/client/components/default/SettingsDefault.js +2 -2
  247. package/src/client/components/itemledger/SettingsItemledger.js +2 -2
  248. package/src/client/components/underpost/AppShellUnderpost.js +3 -2
  249. package/src/client/components/underpost/SettingsUnderpost.js +2 -2
  250. package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
  251. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +313 -30
  252. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
  253. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
  254. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
  255. package/src/client/public/cyberia-docs/CYBERIA.md +48 -28
  256. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
  257. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
  258. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  259. package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
  260. package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
  261. package/src/client/public/default/android-chrome-144x144.png +0 -0
  262. package/src/client/public/default/android-chrome-192x192.png +0 -0
  263. package/src/client/public/default/android-chrome-256x256.png +0 -0
  264. package/src/client/public/default/android-chrome-36x36.png +0 -0
  265. package/src/client/public/default/android-chrome-384x384.png +0 -0
  266. package/src/client/public/default/android-chrome-48x48.png +0 -0
  267. package/src/client/public/default/android-chrome-512x512.png +0 -0
  268. package/src/client/public/default/android-chrome-72x72.png +0 -0
  269. package/src/client/public/default/android-chrome-96x96.png +0 -0
  270. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  271. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  272. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  273. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  274. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  275. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  276. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  277. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  278. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  279. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  280. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  281. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  282. package/src/client/public/default/apple-touch-icon.png +0 -0
  283. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  284. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  285. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  286. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  287. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  288. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  289. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  290. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  291. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  292. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  293. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  294. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  295. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  296. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  297. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  298. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  299. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  300. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  301. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  302. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  303. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  304. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  305. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  306. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  307. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  308. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  309. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  310. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  311. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  312. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  313. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  314. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  315. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  316. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  317. package/src/client/public/default/assets/background/white.jpg +0 -0
  318. package/src/client/public/default/browserconfig.xml +1 -1
  319. package/src/client/public/default/favicon-16x16.png +0 -0
  320. package/src/client/public/default/favicon-32x32.png +0 -0
  321. package/src/client/public/default/favicon-48x48.png +0 -0
  322. package/src/client/public/default/favicon.ico +0 -0
  323. package/src/client/public/default/manifest.webmanifest +5 -5
  324. package/src/client/public/default/mstile-144x144.png +0 -0
  325. package/src/client/public/default/mstile-150x150.png +0 -0
  326. package/src/client/public/default/mstile-310x150.png +0 -0
  327. package/src/client/public/default/mstile-310x310.png +0 -0
  328. package/src/client/public/default/mstile-70x70.png +0 -0
  329. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  330. package/src/client/public/default/yandex-browser-manifest.json +1 -1
  331. package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
  332. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
  333. package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
  334. package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
  335. package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
  336. package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
  337. package/src/client/services/object-layer/object-layer.management.js +6 -10
  338. package/src/client/services/object-layer/object-layer.service.js +3 -1
  339. package/src/client/ssr/RootDocument.js +1 -1
  340. package/src/client/ssr/body/404.js +1 -1
  341. package/src/client/ssr/body/500.js +1 -1
  342. package/src/client/ssr/body/CacheControl.js +1 -1
  343. package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
  344. package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
  345. package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
  346. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
  347. package/src/client/ssr/head/CryptokoynScripts.js +1 -1
  348. package/src/client/ssr/head/Css.js +1 -1
  349. package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
  350. package/src/client/ssr/head/DefaultScripts.js +1 -1
  351. package/src/client/ssr/head/ItemledgerScripts.js +1 -1
  352. package/src/client/ssr/head/Microdata.js +1 -1
  353. package/src/client/ssr/head/Production.js +1 -1
  354. package/src/client/ssr/head/Pwa.js +1 -1
  355. package/src/client/ssr/head/PwaItemledger.js +1 -1
  356. package/src/client/ssr/head/Seo.js +1 -1
  357. package/src/client/ssr/head/UnderpostScripts.js +1 -1
  358. package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
  359. package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
  360. package/src/client/ssr/views/Cyberia404.js +7 -5
  361. package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
  362. package/src/client/ssr/views/Maintenance.js +1 -1
  363. package/src/client/ssr/views/NoNetworkConnection.js +1 -1
  364. package/src/client/ssr/views/Test.js +1 -1
  365. package/src/client/sw/core.sw.js +20 -14
  366. package/src/client-builder/client-build-docs.js +92 -77
  367. package/src/client-builder/client-build-live.js +2 -2
  368. package/src/client-builder/client-build.js +105 -74
  369. package/src/client-builder/client-bundle.js +347 -0
  370. package/src/client-builder/client-dev-server.js +3 -3
  371. package/src/client-builder/client-icons.js +2 -2
  372. package/src/client-builder/ssr.js +3 -3
  373. package/src/client.build.js +3 -6
  374. package/src/client.dev.js +3 -6
  375. package/src/db/DataBaseProvider.js +186 -3
  376. package/src/db/mariadb/MariaDB.js +3 -2
  377. package/src/db/mongo/MongoBootstrap.js +273 -101
  378. package/src/db/mongo/MongoExpress.js +187 -0
  379. package/src/db/mongo/MongooseDB.js +7 -8
  380. package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
  381. package/src/grpc/cyberia/grpc-server.js +6 -8
  382. package/src/index.js +79 -23
  383. package/src/mailer/EmailRender.js +2 -2
  384. package/src/mailer/MailerInterceptor.js +87 -0
  385. package/src/mailer/MailerProvider.js +50 -6
  386. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +144 -147
  387. package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
  388. package/src/projects/cyberia/besu-genesis-generator.js +8 -17
  389. package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
  390. package/src/projects/cyberia/catalog-cyberia.js +54 -10
  391. package/src/projects/cyberia/gemini-client.js +4 -4
  392. package/src/projects/cyberia/generate-saga.js +5 -12
  393. package/src/projects/cyberia/hot-reload-trigger.js +18 -29
  394. package/src/projects/cyberia/instance-backup.js +210 -0
  395. package/src/projects/cyberia/instance-data.js +178 -258
  396. package/src/projects/cyberia/ipfs-client.js +4 -4
  397. package/src/projects/cyberia/map-preview-generator.js +33 -69
  398. package/src/projects/cyberia/object-layer.js +153 -320
  399. package/src/projects/cyberia/seed-audio.js +139 -0
  400. package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
  401. package/src/projects/cyberia/semantic-layer-generator.js +3 -19
  402. package/src/projects/cyberia/stat-balance.js +81 -0
  403. package/src/projects/cyberia/stat-commands.js +23 -0
  404. package/src/projects/cyberia/stat-contract-generator.js +101 -0
  405. package/src/projects/underpost/catalog-underpost.js +9 -1
  406. package/src/proxy.js +4 -7
  407. package/src/runtime/cyberia-client/Dockerfile +17 -8
  408. package/src/runtime/cyberia-client/Dockerfile.dev +13 -4
  409. package/src/runtime/cyberia-server/Dockerfile +18 -6
  410. package/src/runtime/cyberia-server/Dockerfile.dev +16 -3
  411. package/src/runtime/engine-cyberia/Dockerfile +25 -9
  412. package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
  413. package/src/runtime/engine-cyberia/Dockerfile.test +5 -5
  414. package/src/runtime/engine-cyberia/compose.env +17 -5
  415. package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
  416. package/src/runtime/express/Express.js +32 -27
  417. package/src/runtime/lampp/Lampp.js +22 -70
  418. package/src/runtime/nginx/Nginx.js +1 -1
  419. package/src/runtime/wp/Wp.js +16 -48
  420. package/src/server/{catalog.js → build/catalog.js} +15 -5
  421. package/src/server/build/coverage.js +188 -0
  422. package/src/server/build/execution.js +402 -0
  423. package/src/server/build/package.js +508 -0
  424. package/src/server/build/testing.js +578 -0
  425. package/src/server/{dns.js → network/dns.js} +144 -11
  426. package/src/server/{forward-proxy.js → network/forward-proxy.js} +10 -18
  427. package/src/server/{middlewares.js → network/middlewares.js} +11 -5
  428. package/src/server/network/node-capability.js +98 -0
  429. package/src/server/{peer.js → network/peer.js} +3 -3
  430. package/src/server/{proxy.js → network/proxy.js} +7 -13
  431. package/src/server/network/router.js +356 -0
  432. package/src/server/{tls.js → network/tls.js} +2 -2
  433. package/src/server/{underpost-compression.js → network/underpost-compression.js} +1 -1
  434. package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +7 -7
  435. package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +2 -2
  436. package/src/server/{cri.js → ops/cri.js} +2 -2
  437. package/src/server/{cron.js → ops/cron.js} +349 -74
  438. package/src/server/ops/event-notification.js +284 -0
  439. package/src/server/{logger.js → ops/logger.js} +143 -23
  440. package/src/server/ops/monitoring.js +1724 -0
  441. package/src/server/{systemd.js → ops/systemd.js} +55 -1
  442. package/src/server/{conf.js → runtime/conf.js} +516 -423
  443. package/src/server/runtime/config-scope.js +215 -0
  444. package/src/server/runtime/environment.js +149 -0
  445. package/src/server/{process.js → runtime/process.js} +153 -12
  446. package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
  447. package/src/server/{runtime.js → runtime/runtime.js} +12 -8
  448. package/src/server/{start.js → runtime/start.js} +128 -39
  449. package/src/server/{auth.js → security/auth.js} +7 -8
  450. package/src/server/security/container-storage.js +382 -0
  451. package/src/server/{crypto.js → security/crypto.js} +1 -1
  452. package/src/server/{selinux.js → security/selinux.js} +1 -1
  453. package/src/server/{backup.js → storage/backup.js} +17 -8
  454. package/src/server/{data-query.js → storage/data-query.js} +17 -1
  455. package/src/server/storage/downloader.js +121 -0
  456. package/src/server/storage/repository.js +68 -0
  457. package/src/server/storage/zip.js +153 -0
  458. package/src/server.js +4 -7
  459. package/src/ws/IoInterface.js +1 -1
  460. package/src/ws/IoServer.js +1 -1
  461. package/src/ws/core/core.ws.connection.js +1 -1
  462. package/src/ws/core/core.ws.emit.js +1 -1
  463. package/src/ws/core/core.ws.server.js +1 -1
  464. package/src/ws/default/default.ws.connection.js +1 -1
  465. package/src/ws/default/default.ws.emit.js +1 -1
  466. package/src/ws/default/default.ws.server.js +1 -1
  467. package/test/e2e/event-e2e-public-ingress-down.js +45 -0
  468. package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
  469. package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
  470. package/test/{api.test.js → integration/app/api.test.js} +33 -14
  471. package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
  472. package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
  473. package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +64 -0
  474. package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
  475. package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
  476. package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +17 -23
  477. package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
  478. package/test/integration/app/cyberia/cyberia-load.test.js +466 -0
  479. package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
  480. package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
  481. package/test/integration/app/cyberia/fallback-world-capture.test.js +338 -0
  482. package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
  483. package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
  484. package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
  485. package/test/integration/app/cyberia/seed-audio.test.js +275 -0
  486. package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
  487. package/test/integration/infra/1-security/config-scope.test.js +305 -0
  488. package/test/integration/infra/1-security/container-storage.test.js +356 -0
  489. package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
  490. package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
  491. package/test/{selinux.test.js → integration/infra/1-security/selinux.test.js} +2 -4
  492. package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
  493. package/test/integration/infra/1-security/systemd-service.test.js +70 -0
  494. package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
  495. package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
  496. package/test/integration/infra/2-network/node-capability.test.js +182 -0
  497. package/test/integration/infra/2-network/wireguard-cli.test.js +1187 -0
  498. package/test/{wireguard-edge.test.js → integration/infra/2-network/wireguard-edge.test.js} +649 -55
  499. package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
  500. package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
  501. package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
  502. package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
  503. package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
  504. package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
  505. package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
  506. package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
  507. package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +6 -6
  508. package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +4 -4
  509. package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
  510. package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
  511. package/test/integration/infra/5-observability/event-notification.test.js +197 -0
  512. package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
  513. package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
  514. package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
  515. package/test/support/shell-harness.js +73 -0
  516. package/test/unit/build-template.test.js +97 -0
  517. package/test/unit/build-workflow-offline.test.js +132 -0
  518. package/test/unit/catalog.test.js +71 -0
  519. package/test/unit/client-build-docs.test.js +361 -0
  520. package/test/unit/client-bundle.test.js +313 -0
  521. package/test/unit/conf-loading.test.js +303 -0
  522. package/test/unit/conf-resolution.test.js +996 -0
  523. package/test/unit/coverage-artifact.test.js +221 -0
  524. package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
  525. package/test/unit/cyberia/instance-backup.test.js +183 -0
  526. package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
  527. package/test/unit/cyberia/publish-workflow.test.js +22 -0
  528. package/test/unit/cyberia/stat-balance.test.js +69 -0
  529. package/test/unit/deploy-env-resolution.test.js +38 -0
  530. package/test/unit/deploy-log-table.test.js +518 -0
  531. package/test/unit/downloader-integrity.test.js +98 -0
  532. package/test/unit/execution-profiles.test.js +219 -0
  533. package/test/unit/file-reference-registry.test.js +141 -0
  534. package/test/unit/fleet-sync-source.test.js +149 -0
  535. package/test/unit/fs-storage-paths.test.js +596 -0
  536. package/test/unit/logger-redaction.test.js +141 -0
  537. package/test/unit/package.test.js +457 -0
  538. package/test/unit/prepare-host.test.js +382 -0
  539. package/test/unit/process-environment.test.js +18 -0
  540. package/test/unit/propagation-message.test.js +78 -0
  541. package/test/unit/redeploy-plan.test.js +24 -0
  542. package/test/unit/release-bump.test.js +474 -0
  543. package/test/unit/ssh-output-redaction.test.js +28 -0
  544. package/test/unit/start-options.test.js +46 -0
  545. package/test/unit/test-tiers.test.js +220 -0
  546. package/test/unit/zip-archive.test.js +142 -0
  547. package/vitest.config.js +66 -0
  548. package/.nycrc +0 -9
  549. package/deploy/lib/logging.sh +0 -96
  550. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
  551. package/manifests/mongodb/pv-pvc.yaml +0 -59
  552. package/scripts/coverall-test-cyberia.sh +0 -24
  553. package/scripts/coverall-test.sh +0 -24
  554. package/scripts/link-local-underpost-cli.sh +0 -6
  555. package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
  556. package/src/api/user/user.build.js +0 -16
  557. package/src/cli/env.js +0 -177
  558. package/src/client/components/core/Blockchain.js +0 -41
  559. package/src/client/components/core/Blog.js +0 -9
  560. package/src/client/components/core/KeyboardAvoidance.js +0 -145
  561. package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
  562. package/src/client/public/default/assets/background/dark.jpg +0 -0
  563. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  564. package/src/client/public/default/assets/background/white0.jpg +0 -0
  565. package/src/client/public/doc/favicon.ico +0 -0
  566. package/src/client/public/doc/sitemap +0 -148
  567. package/src/server/downloader.js +0 -73
  568. package/src/server/environment.js +0 -98
@@ -24,12 +24,12 @@ MODE=runtime # runtime | instance
24
24
  ENV=development # development | production
25
25
  DEPLOY_ID=dd-test # deploy id (instance mode: parent of conf.instances.json)
26
26
  INSTANCE_IDS= # instance mode: csv of ids (default: all in conf.instances.json)
27
- IMAGE=underpost/wp:v3.3.0 # runtime mode image (instance mode reads image from conf)
27
+ IMAGE=underpost/wp:v3.3.76 # runtime mode image (instance mode reads image from conf)
28
28
  VERSIONS=green # csv of blue/green versions
29
29
  REPLICAS=1 # replicas per deployment
30
30
  NAMESPACE=default # k8s namespace
31
31
  CLUSTER=kind # kind | kubeadm | k3s | "" (auto/none)
32
- TIMEOUT_RESPONSE=300000ms # HTTPProxy per-route response timeout
32
+ TIMEOUT_RESPONSE=10000ms # HTTPProxy per-route response timeout
33
33
  TEMPLATE_REPO=underpostnet/pwa-microservices-template-private # runtime mode link repo
34
34
  ENVOY_NAMESPACE=projectcontour # ingress namespace (instance TLS exposure)
35
35
  ENVOY_SERVICE=envoy # ingress service (instance TLS exposure)
@@ -59,7 +59,7 @@ Common (every default is overridable):
59
59
  --replicas <n>
60
60
  --namespace <ns>
61
61
  --cluster <kind|kubeadm|k3s|none>
62
- --timeout-response <dur> e.g. 300000ms
62
+ --timeout-response <dur> e.g. 10000ms
63
63
  --template-repo <owner/repo> runtime mode link repo
64
64
  --envoy-namespace <ns> instance TLS exposure ingress namespace
65
65
  --envoy-service <name> instance TLS exposure ingress service
@@ -176,7 +176,7 @@ hosts_from() {
176
176
 
177
177
  # ─────────────────────────── runtime mode ───────────────────────────
178
178
  run_runtime_mode() {
179
- local link_cmd="cd /home/dd,underpost clone ${TEMPLATE_REPO},cd /home/dd/${TEMPLATE_REPO##*/},npm install,npm link"
179
+ local link_cmd="cd /home/dd,underpost clone ${TEMPLATE_REPO},cd /home/dd/${TEMPLATE_REPO##*/},npm install,npm link --force"
180
180
  local deploy_cmd proxy_flag="" expose_flags="" start_flags=""
181
181
 
182
182
  # Publish the local engine src to underpostnet/engine-test-<id> so the pod
@@ -220,7 +220,7 @@ run_instance_mode() {
220
220
  for id in "${ids[@]}"; do
221
221
  [ -n "$id" ] || continue
222
222
  echo "[test-monitor] deploying instance ${DEPLOY_ID},${id}"
223
- node bin run instance "${DEPLOY_ID},${id},${REPLICAS}" \
223
+ node bin run instance --deploy-id "$DEPLOY_ID" --instance-id "$id" --replicas "$REPLICAS" \
224
224
  $DEV_FLAG $CLUSTER_FLAG --namespace "$NAMESPACE" --etc-hosts $tls_flag \
225
225
  ${IMAGE:+--image-name "$IMAGE"}
226
226
  done
@@ -4,9 +4,21 @@ import {
4
4
  sendBlob,
5
5
  serviceHandler,
6
6
  setCrossOriginHeaders,
7
- } from '../../server/middlewares.js';
7
+ } from '../../server/network/middlewares.js';
8
8
  import { AtlasSpriteSheetService } from './atlas-sprite-sheet.service.js';
9
9
 
10
+ /* Streams one render as a file. Headers go on before the lookup, so a cross-origin
11
+ * client can read a 404 too. */
12
+ const blobHandler = (lookup) =>
13
+ controllerHandler(
14
+ async (req, res, options) => {
15
+ setCrossOriginHeaders(req, res);
16
+ const { buffer, mimetype, name } = await lookup(req, res, options);
17
+ return sendBlob(req, res, { buffer, mimetype, filename: name });
18
+ },
19
+ { errorStatus: 404 },
20
+ );
21
+
10
22
  const AtlasSpriteSheetController = buildCrudController(AtlasSpriteSheetService, {
11
23
  get: serviceHandler(AtlasSpriteSheetService.get, { crossOrigin: true, pagination: true }),
12
24
  getMetadata: serviceHandler(AtlasSpriteSheetService.getMetadata, {
@@ -16,15 +28,8 @@ const AtlasSpriteSheetController = buildCrudController(AtlasSpriteSheetService,
16
28
  }),
17
29
  generate: serviceHandler(AtlasSpriteSheetService.generate, { errorStatus: 500 }),
18
30
  deleteByObjectLayerId: serviceHandler(AtlasSpriteSheetService.deleteByObjectLayerId, { errorStatus: 500 }),
19
- blob: controllerHandler(
20
- async (req, res, options) => {
21
- // Set before the service call so cross-origin clients can read 404s too.
22
- setCrossOriginHeaders(req, res);
23
- const { buffer, mimetype, name } = await AtlasSpriteSheetService.blob(req, res, options);
24
- return sendBlob(req, res, { buffer, mimetype, filename: name });
25
- },
26
- { errorStatus: 404 },
27
- ),
31
+ blob: blobHandler(AtlasSpriteSheetService.blob),
32
+ idlePreview: blobHandler(AtlasSpriteSheetService.idlePreview),
28
33
  });
29
34
 
30
35
  export { AtlasSpriteSheetController };
@@ -69,14 +69,27 @@ const DirectionFramesSchema = new Schema(
69
69
  { _id: false },
70
70
  );
71
71
  /**
72
+ * One atlas per item key, kept in two renders of one layout, plus the still that
73
+ * stands in for the item wherever a single picture is wanted.
74
+ *
75
+ * `fileId` is the human-resolution PNG, at `metadata.upscaleFactor` pixels per
76
+ * cell. `minifyFileId` is the PNG the client runtime downloads through
77
+ * `GET /atlas-sprite-sheet/blob/:itemKey`, at `metadata.cellPixelDim` pixels per
78
+ * cell. `metadata` describes the minified render, so blob and metadata agree.
79
+ * `idlePreviewFileId` is the first down-idle frame cut out of `fileId`, served by
80
+ * `GET /atlas-sprite-sheet/idle-preview/:itemKey` to every editor and overlay.
81
+ *
72
82
  * @typedef {Object} AtlasSpriteSheet
73
- * @property {Types.ObjectId} fileId - Reference to File document (consolidated PNG)
83
+ * @property {Types.ObjectId} fileId - Reference to the human-resolution PNG File document
84
+ * @property {Types.ObjectId} [minifyFileId] - Reference to the minified PNG File document
85
+ * @property {Types.ObjectId} [idlePreviewFileId] - Reference to the down-idle still File document
74
86
  * @property {string} [cid] - IPFS Content Identifier for the atlas PNG
75
87
  * @property {Object} metadata - Atlas sprite sheet metadata
76
88
  * @property {string} metadata.itemKey - Item identifier key for texture reference
77
- * @property {number} metadata.atlasWidth - Total atlas width in pixels
78
- * @property {number} metadata.atlasHeight - Total atlas height in pixels
79
- * @property {number} metadata.cellPixelDim - Pixel dimension of each cell
89
+ * @property {number} metadata.atlasWidth - Minified atlas width in pixels
90
+ * @property {number} metadata.atlasHeight - Minified atlas height in pixels
91
+ * @property {number} metadata.cellPixelDim - Pixels per cell of the minified render
92
+ * @property {number} metadata.upscaleFactor - Pixels per cell of the human-resolution render
80
93
  * @property {number} metadata.frame_duration - Duration of each frame in milliseconds
81
94
  * @property {DirectionFrames} metadata.frames - Frame positions in atlas by direction
82
95
  * @property {Date} createdAt - When the document was created
@@ -90,6 +103,18 @@ const AtlasSpriteSheetSchema = new Schema(
90
103
  ref: 'File',
91
104
  required: true,
92
105
  },
106
+ // Absent until `cyberia ol --minify` renders it for this item.
107
+ minifyFileId: {
108
+ type: Schema.Types.ObjectId,
109
+ ref: 'File',
110
+ default: null,
111
+ },
112
+ // The down-idle still every preview reads; absent until an atlas write fills it.
113
+ idlePreviewFileId: {
114
+ type: Schema.Types.ObjectId,
115
+ ref: 'File',
116
+ default: null,
117
+ },
93
118
  cid: {
94
119
  type: String,
95
120
  default: '',
@@ -99,7 +124,8 @@ const AtlasSpriteSheetSchema = new Schema(
99
124
  itemKey: { type: String, required: true, trim: true },
100
125
  atlasWidth: { type: Number, required: true, min: 1 },
101
126
  atlasHeight: { type: Number, required: true, min: 1 },
102
- cellPixelDim: { type: Number, required: true, min: 1, default: 20 },
127
+ cellPixelDim: { type: Number, required: true, min: 1 },
128
+ upscaleFactor: { type: Number, required: false, min: 1 },
103
129
  frame_duration: { type: Number, min: 0, default: 100 },
104
130
  frames: { type: DirectionFramesSchema, required: true },
105
131
  },
@@ -113,6 +139,8 @@ const AtlasSpriteSheetSchema = new Schema(
113
139
  // Indexes for efficient querying
114
140
  AtlasSpriteSheetSchema.index({ 'metadata.itemKey': 1 }, { unique: true });
115
141
  AtlasSpriteSheetSchema.index({ fileId: 1 });
142
+ AtlasSpriteSheetSchema.index({ minifyFileId: 1 });
143
+ AtlasSpriteSheetSchema.index({ idlePreviewFileId: 1 });
116
144
  // Pre-save validation
117
145
  AtlasSpriteSheetSchema.pre('save', function () {
118
146
  if (!this.fileId || !this.metadata) {
@@ -127,6 +155,8 @@ class AtlasSpriteSheetDto {
127
155
  return {
128
156
  _id: 1,
129
157
  fileId: 1,
158
+ minifyFileId: 1,
159
+ idlePreviewFileId: 1,
130
160
  cid: 1,
131
161
  metadata: 1,
132
162
  createdAt: 1,
@@ -144,6 +174,7 @@ class AtlasSpriteSheetDto {
144
174
  'metadata.atlasWidth': 1,
145
175
  'metadata.atlasHeight': 1,
146
176
  'metadata.cellPixelDim': 1,
177
+ 'metadata.upscaleFactor': 1,
147
178
  'metadata.frame_duration': 1,
148
179
  'metadata.frames': 1,
149
180
  createdAt: 1,
@@ -1,6 +1,6 @@
1
1
  import express from 'express';
2
- import { registerCrudRoutes } from '../../server/middlewares.js';
3
- import { moderatorGuard } from '../../server/auth.js';
2
+ import { registerCrudRoutes } from '../../server/network/middlewares.js';
3
+ import { moderatorGuard } from '../../server/security/auth.js';
4
4
  import { AtlasSpriteSheetController } from './atlas-sprite-sheet.controller.js';
5
5
 
6
6
  class AtlasSpriteSheetRouter {
@@ -23,6 +23,11 @@ class AtlasSpriteSheetRouter {
23
23
  async (req, res) => await AtlasSpriteSheetController.deleteByObjectLayerId(req, res, options),
24
24
  );
25
25
  router.get(`/blob/:itemKey`, async (req, res) => await AtlasSpriteSheetController.blob(req, res, options));
26
+ // The down-idle still of an item, for every editor and overlay that shows one picture of it.
27
+ router.get(
28
+ `/idle-preview/:itemKey`,
29
+ async (req, res) => await AtlasSpriteSheetController.idlePreview(req, res, options),
30
+ );
26
31
  // Metadata endpoints: returns itemKey, atlasWidth, atlasHeight, cellPixelDim, frames (no fileId).
27
32
  // Client fetches /metadata/:itemKey once, caches it, then fetches /blob/:itemKey for the PNG.
28
33
  router.get(
@@ -1,11 +1,15 @@
1
1
  import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
- import { loggerFactory } from '../../server/logger.js';
3
- import { DataQuery } from '../../server/data-query.js';
4
- import { AtlasSpriteSheetGenerator } from '../../projects/cyberia/atlas-sprite-sheet-generator.js';
5
- import { FileFactory } from '../file/file.service.js';
2
+ import { loggerFactory } from '../../server/ops/logger.js';
3
+ import { DataQuery } from '../../server/storage/data-query.js';
4
+ import { FileCleanup } from '../file/file.service.js';
6
5
  import { AtlasSpriteSheetDto } from './atlas-sprite-sheet.model.js';
7
6
  import { IpfsClient } from '../../projects/cyberia/ipfs-client.js';
8
- import { createPinRecord, removePinRecordsAndUnpin } from '../ipfs/ipfs.service.js';
7
+ import { removePinRecordsAndUnpin } from '../ipfs/ipfs.service.js';
8
+ import {
9
+ ATLAS_FILE_FIELDS,
10
+ AtlasSpriteSheetStore,
11
+ atlasMfsPaths,
12
+ } from '../../projects/cyberia/atlas-sprite-sheet-store.js';
9
13
 
10
14
  const logger = loggerFactory(import.meta);
11
15
  const DEFAULT_ATLAS_FRAME_DURATION = 100;
@@ -51,133 +55,91 @@ async function withResolvedAtlasFrameDuration(doc, ObjectLayer) {
51
55
  };
52
56
  }
53
57
 
58
+ /**
59
+ * Removes one atlas: its IPFS pins and MFS entries, both render File documents,
60
+ * and the AtlasSpriteSheet document itself.
61
+ *
62
+ * @param {Object} params
63
+ * @param {Object} params.atlasDoc - The AtlasSpriteSheet document.
64
+ * @param {Object} params.options - Router options ({ host, path }).
65
+ * @param {string} [params.itemKey] - Item key, when the caller already resolved it.
66
+ * @param {string} [params.metadataCid] - Atlas metadata CID, when the object layer holds it.
67
+ * @returns {Promise<void>}
68
+ */
69
+ const purgeAtlasDoc = async ({ atlasDoc, options, itemKey, metadataCid }) => {
70
+ const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
71
+ const File = DataBaseProviderService.getModel('File', options);
72
+ const key = itemKey || atlasDoc.metadata?.itemKey;
73
+ const mfsPaths = key ? atlasMfsPaths(key) : null;
74
+
75
+ for (const [cid, mfsPath] of [
76
+ [atlasDoc.cid, mfsPaths?.png],
77
+ [metadataCid, mfsPaths?.metadata],
78
+ ]) {
79
+ if (!cid) continue;
80
+ try {
81
+ await removePinRecordsAndUnpin(cid, options);
82
+ if (mfsPath) await IpfsClient.removeMfsPath(mfsPath);
83
+ logger.info(`Cleaned up IPFS CID ${cid} for AtlasSpriteSheet ${atlasDoc._id}`);
84
+ } catch (ipfsErr) {
85
+ logger.warn(`Failed to clean up IPFS CID ${cid}: ${ipfsErr.message}`);
86
+ }
87
+ }
88
+
89
+ await FileCleanup.deleteDocumentFiles({ doc: atlasDoc, fileFields: ATLAS_FILE_FIELDS, File });
90
+ await AtlasSpriteSheet.findByIdAndDelete(atlasDoc._id);
91
+ };
92
+
54
93
  class AtlasSpriteSheetService {
55
- static blob = async (req, res, options) => {
94
+ // Serves the minified render, the one `metadata` describes. The client runtime
95
+ // pairs this blob with GET /metadata/:itemKey, so the two must be the same layout.
96
+ /* One render of an item's atlas, by the File field that holds it. */
97
+ static render = async ({ itemKey, field, label }, options) => {
56
98
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
57
99
  const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
58
100
  /** @type {import('../file/file.model.js').FileModel} */
59
101
  const File = DataBaseProviderService.getModel('File', options);
60
102
 
61
- const itemKey = req.params.itemKey;
62
103
  const atlasDoc = await AtlasSpriteSheet.findOne({ 'metadata.itemKey': itemKey }).lean();
63
104
  if (!atlasDoc) throw new Error(`Atlas not found for itemKey: ${itemKey}`);
105
+ if (!atlasDoc[field]) throw new Error(`${label} missing for itemKey: ${itemKey}`);
64
106
 
65
- const fileDoc = await File.findById(atlasDoc.fileId);
107
+ const fileDoc = await File.findById(atlasDoc[field]);
66
108
  if (!fileDoc || !fileDoc.data) throw new Error(`File not found for atlas itemKey: ${itemKey}`);
67
109
 
68
110
  return { buffer: Buffer.from(fileDoc.data), mimetype: fileDoc.mimetype || 'image/png', name: fileDoc.name };
69
111
  };
70
- static generate = async (req, res, options, generateOptions = {}) => {
71
- /** @type {import('../object-layer/object-layer.model.js').ObjectLayerModel} */
72
- const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
73
- /** @type {import('../file/file.model.js').FileModel} */
74
- const File = DataBaseProviderService.getModel('File', options);
75
- /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
76
- const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
77
112
 
78
- let objectLayer = req.objectLayer;
79
-
80
- if (!objectLayer) {
81
- objectLayer = await ObjectLayer.findById(req.params.id).populate('objectLayerRenderFramesId');
82
- }
83
-
84
- if (!objectLayer) {
85
- throw new Error('ObjectLayer not found');
86
- }
87
-
88
- if (!objectLayer.objectLayerRenderFramesId) {
89
- throw new Error('ObjectLayer has no render frames');
90
- }
91
-
92
- const itemKey = objectLayer.data.item.id;
93
- const { buffer, metadata } = await AtlasSpriteSheetGenerator.generateAtlas(
94
- objectLayer.objectLayerRenderFramesId,
95
- itemKey,
113
+ static blob = (req, res, options) =>
114
+ AtlasSpriteSheetService.render(
115
+ { itemKey: req.params.itemKey, field: 'minifyFileId', label: 'Minified atlas render' },
116
+ options,
96
117
  );
97
118
 
98
- const fileDoc = await new File(FileFactory.create(buffer, `${itemKey}.png`)).save();
99
-
100
- // Add atlas PNG to IPFS and obtain its CID
101
- let atlasCid = '';
102
- let atlasMetadataCid = '';
103
- const userId = req.auth && req.auth.user ? req.auth.user._id : undefined;
104
- try {
105
- const ipfsResult = await IpfsClient.addBufferToIpfs(
106
- buffer,
107
- `${itemKey}_atlas_sprite_sheet.png`,
108
- `/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet.png`,
109
- );
110
- if (ipfsResult) {
111
- atlasCid = ipfsResult.cid;
112
- logger.info(`Atlas sprite sheet pinned to IPFS – CID: ${atlasCid}`);
113
- }
114
- } catch (ipfsError) {
115
- logger.warn('Failed to add atlas sprite sheet to IPFS:', ipfsError.message);
116
- }
117
-
118
- // Pin atlas metadata JSON to IPFS (fast-json-stable-stringify) and obtain its CID
119
- try {
120
- const metadataIpfsResult = await IpfsClient.addJsonToIpfs(
121
- metadata,
122
- `${itemKey}_atlas_sprite_sheet_metadata.json`,
123
- `/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet_metadata.json`,
124
- );
125
- if (metadataIpfsResult) {
126
- atlasMetadataCid = metadataIpfsResult.cid;
127
- logger.info(`Atlas metadata pinned to IPFS – CID: ${atlasMetadataCid}`);
128
- }
129
- } catch (ipfsError) {
130
- logger.warn('Failed to add atlas metadata to IPFS:', ipfsError.message);
131
- }
119
+ static idlePreview = (req, res, options) =>
120
+ AtlasSpriteSheetService.render(
121
+ { itemKey: req.params.itemKey, field: 'idlePreviewFileId', label: 'Idle preview' },
122
+ options,
123
+ );
124
+ static generate = async (req, res, options, generateOptions = {}) => {
125
+ /** @type {import('../object-layer/object-layer.model.js').ObjectLayerModel} */
126
+ const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
132
127
 
133
- let atlasDoc = await AtlasSpriteSheet.findOne({ 'metadata.itemKey': itemKey });
128
+ const objectLayer =
129
+ req.objectLayer || (await ObjectLayer.findById(req.params.id).populate('objectLayerRenderFramesId'));
134
130
 
135
- if (atlasDoc) {
136
- // Clean up old file if it exists
137
- if (atlasDoc.fileId) {
138
- await File.findByIdAndDelete(atlasDoc.fileId);
139
- }
140
- atlasDoc.fileId = fileDoc._id;
141
- atlasDoc.cid = atlasCid;
142
- atlasDoc.metadata = metadata;
143
- await atlasDoc.save();
144
- } else {
145
- atlasDoc = await new AtlasSpriteSheet({
146
- fileId: fileDoc._id,
147
- cid: atlasCid,
148
- metadata,
149
- }).save();
150
- }
131
+ if (!objectLayer) throw new Error('ObjectLayer not found');
132
+ if (!objectLayer.objectLayerRenderFramesId) throw new Error('ObjectLayer has no render frames');
151
133
 
152
- // Register CIDs in the IPFS registry now that atlasDoc._id is known.
153
- if (atlasCid) {
154
- try {
155
- await createPinRecord({
156
- cid: atlasCid,
157
- resourceType: 'atlas-sprite-sheet',
158
- mfsPath: `/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet.png`,
159
- options,
160
- });
161
- } catch (e) {
162
- logger.warn('IPFS registry update failed (atlas PNG):', e.message);
163
- }
164
- }
165
- if (atlasMetadataCid) {
166
- try {
167
- await createPinRecord({
168
- cid: atlasMetadataCid,
169
- resourceType: 'atlas-metadata',
170
- mfsPath: `/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet_metadata.json`,
171
- options,
172
- });
173
- } catch (e) {
174
- logger.warn('IPFS registry update failed (atlas metadata):', e.message);
175
- }
176
- }
134
+ const { atlasDoc, atlasCid, atlasMetadataCid } = await AtlasSpriteSheetStore.persist({
135
+ itemKey: objectLayer.data.item.id,
136
+ objectLayerRenderFrames: objectLayer.objectLayerRenderFramesId,
137
+ upscaleFactor: generateOptions.upscaleFactor,
138
+ options,
139
+ });
177
140
 
178
- // When skipObjectLayerSave is set, return CIDs without mutating the OL document.
179
- // This enables cut-over consistency: callers stage CIDs in memory and write the
180
- // ObjectLayer atomically only after all CIDs are computed.
141
+ // Callers that stage CIDs in memory write the ObjectLayer themselves, so the
142
+ // document stays untouched until every CID is known.
181
143
  if (generateOptions.skipObjectLayerSave) {
182
144
  return { atlasDoc, atlasCid, atlasMetadataCid };
183
145
  }
@@ -194,8 +156,6 @@ class AtlasSpriteSheetService {
194
156
  static deleteByObjectLayerId = async (req, res, options) => {
195
157
  /** @type {import('../object-layer/object-layer.model.js').ObjectLayerModel} */
196
158
  const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
197
- /** @type {import('../file/file.model.js').FileModel} */
198
- const File = DataBaseProviderService.getModel('File', options);
199
159
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
200
160
  const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
201
161
 
@@ -207,37 +167,12 @@ class AtlasSpriteSheetService {
207
167
  if (objectLayer.atlasSpriteSheetId) {
208
168
  const atlasDoc = await AtlasSpriteSheet.findById(objectLayer.atlasSpriteSheetId);
209
169
  if (atlasDoc) {
210
- // Remove pin records and unpin atlas CID from IPFS
211
- const atlasCid = atlasDoc.cid || objectLayer.data.render?.cid;
212
- const atlasMetadataCid = objectLayer.data.render?.metadataCid;
213
- if (atlasCid) {
214
- try {
215
- await removePinRecordsAndUnpin(atlasCid, options);
216
- // Remove the MFS entry for the atlas sprite sheet PNG
217
- const itemId = objectLayer.data.item.id;
218
- await IpfsClient.removeMfsPath(`/object-layer/${itemId}/${itemId}_atlas_sprite_sheet.png`);
219
- logger.info(`Cleaned up IPFS atlas CID ${atlasCid} for ObjectLayer ${objectLayer._id}`);
220
- } catch (ipfsErr) {
221
- logger.warn(`Failed to clean up IPFS atlas CID ${atlasCid}: ${ipfsErr.message}`);
222
- }
223
- }
224
- if (atlasMetadataCid) {
225
- try {
226
- await removePinRecordsAndUnpin(atlasMetadataCid, options);
227
- const itemId = objectLayer.data.item.id;
228
- await IpfsClient.removeMfsPath(`/object-layer/${itemId}/${itemId}_atlas_sprite_sheet_metadata.json`);
229
- logger.info(`Cleaned up IPFS atlas metadata CID ${atlasMetadataCid} for ObjectLayer ${objectLayer._id}`);
230
- } catch (ipfsErr) {
231
- logger.warn(`Failed to clean up IPFS atlas metadata CID ${atlasMetadataCid}: ${ipfsErr.message}`);
232
- }
233
- }
234
-
235
- // Delete the atlas File document from MongoDB
236
- if (atlasDoc.fileId) {
237
- await File.findByIdAndDelete(atlasDoc.fileId);
238
- }
239
- // Delete the AtlasSpriteSheet document itself
240
- await AtlasSpriteSheet.findByIdAndDelete(atlasDoc._id);
170
+ await purgeAtlasDoc({
171
+ atlasDoc,
172
+ options,
173
+ itemKey: objectLayer.data.item.id,
174
+ metadataCid: objectLayer.data.render?.metadataCid,
175
+ });
241
176
  }
242
177
  objectLayer.atlasSpriteSheetId = undefined;
243
178
  if (!objectLayer.data.render) objectLayer.data.render = {};
@@ -328,54 +263,23 @@ class AtlasSpriteSheetService {
328
263
  static delete = async (req, res, options) => {
329
264
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
330
265
  const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
331
- /** @type {import('../file/file.model.js').FileModel} */
332
- const File = DataBaseProviderService.getModel('File', options);
333
266
 
334
267
  if (req.params.id) {
335
268
  const atlasDoc = await AtlasSpriteSheet.findById(req.params.id);
336
269
  if (!atlasDoc) return null;
270
+ await purgeAtlasDoc({ atlasDoc, options });
271
+ return atlasDoc;
272
+ }
337
273
 
338
- // Remove pin records and unpin atlas CID from IPFS
339
- if (atlasDoc.cid) {
340
- try {
341
- await removePinRecordsAndUnpin(atlasDoc.cid, options);
342
- if (atlasDoc.metadata?.itemKey) {
343
- const itemKey = atlasDoc.metadata.itemKey;
344
- await IpfsClient.removeMfsPath(`/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet.png`);
345
- }
346
- logger.info(`Cleaned up IPFS atlas CID ${atlasDoc.cid} for AtlasSpriteSheet ${atlasDoc._id}`);
347
- } catch (ipfsErr) {
348
- logger.warn(`Failed to clean up IPFS atlas CID ${atlasDoc.cid}: ${ipfsErr.message}`);
349
- }
350
- }
351
-
352
- // Delete the referenced File document (the atlas PNG blob)
353
- if (atlasDoc.fileId) {
354
- await File.findByIdAndDelete(atlasDoc.fileId);
355
- }
356
-
357
- return await AtlasSpriteSheet.findByIdAndDelete(req.params.id);
358
- } else {
359
- // Bulk delete: iterate each atlas to clean up File, IPFS pins, and pin records
360
- const allAtlases = await AtlasSpriteSheet.find({});
361
- for (const atlasDoc of allAtlases) {
362
- try {
363
- if (atlasDoc.cid) {
364
- await removePinRecordsAndUnpin(atlasDoc.cid, options);
365
- if (atlasDoc.metadata?.itemKey) {
366
- const itemKey = atlasDoc.metadata.itemKey;
367
- await IpfsClient.removeMfsPath(`/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet.png`);
368
- }
369
- }
370
- if (atlasDoc.fileId) {
371
- await File.findByIdAndDelete(atlasDoc.fileId);
372
- }
373
- } catch (err) {
374
- logger.error(`Failed to clean up AtlasSpriteSheet ${atlasDoc._id} during bulk delete: ${err.message}`);
375
- }
274
+ const allAtlases = await AtlasSpriteSheet.find({});
275
+ for (const atlasDoc of allAtlases) {
276
+ try {
277
+ await purgeAtlasDoc({ atlasDoc, options });
278
+ } catch (err) {
279
+ logger.error(`Failed to clean up AtlasSpriteSheet ${atlasDoc._id} during bulk delete: ${err.message}`);
376
280
  }
377
- return await AtlasSpriteSheet.deleteMany();
378
281
  }
282
+ return { deletedCount: allAtlases.length };
379
283
  };
380
284
  }
381
285
 
@@ -1,4 +1,4 @@
1
- import { buildCrudController, serviceHandler } from '../../server/middlewares.js';
1
+ import { buildCrudController, serviceHandler } from '../../server/network/middlewares.js';
2
2
  import { CoreService } from './core.service.js';
3
3
 
4
4
  const CoreController = buildCrudController(CoreService, {
@@ -1,6 +1,6 @@
1
1
  import express from 'express';
2
- import { registerCrudRoutes } from '../../server/middlewares.js';
3
- import { adminGuard } from '../../server/auth.js';
2
+ import { registerCrudRoutes } from '../../server/network/middlewares.js';
3
+ import { adminGuard } from '../../server/security/auth.js';
4
4
  import { CoreController } from './core.controller.js';
5
5
 
6
6
  class CoreRouter {
@@ -1,6 +1,6 @@
1
1
  import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
- import { loggerFactory } from '../../server/logger.js';
3
- import { shellExec } from '../../server/process.js';
2
+ import { loggerFactory } from '../../server/ops/logger.js';
3
+ import { shellExec } from '../../server/runtime/process.js';
4
4
 
5
5
  const logger = loggerFactory(import.meta);
6
6
 
@@ -1,4 +1,4 @@
1
- import { serviceHandler } from '../../server/middlewares.js';
1
+ import { serviceHandler } from '../../server/network/middlewares.js';
2
2
  import { CryptoService } from './crypto.service.js';
3
3
 
4
4
  class CryptoController {
@@ -1,4 +1,4 @@
1
- import { loggerFactory } from '../../server/logger.js';
1
+ import { loggerFactory } from '../../server/ops/logger.js';
2
2
  import crypto from 'crypto';
3
3
  import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
4
4
  const logger = loggerFactory(import.meta);
@@ -1,4 +1,4 @@
1
- import { buildCrudController, serviceHandler } from '../../server/middlewares.js';
1
+ import { buildCrudController, serviceHandler } from '../../server/network/middlewares.js';
2
2
  import { CyberiaActionService } from './cyberia-action.service.js';
3
3
 
4
4
  const CyberiaActionController = buildCrudController(CyberiaActionService, {
@@ -1,5 +1,5 @@
1
1
  import express from 'express';
2
- import { registerCrudRoutes } from '../../server/middlewares.js';
2
+ import { registerCrudRoutes } from '../../server/network/middlewares.js';
3
3
  import { CyberiaActionController } from './cyberia-action.controller.js';
4
4
 
5
5
  class CyberiaActionRouter {
@@ -9,8 +9,8 @@ class CyberiaActionRouter {
9
9
  */
10
10
  static router(options) {
11
11
  const router = express.Router();
12
- // Direct lookup by code the client fetches an NPC's action metadata
13
- // (label, dialogue map) by the action code the Go server sends over AOI.
12
+ // Direct lookup by code. The client fetches an NPC's action metadata
13
+ // (label, dialogue map) by the action code the AOI stream carries.
14
14
  router.get(`/code/:code`, async (req, res) => await CyberiaActionController.getByCode(req, res, options));
15
15
  return registerCrudRoutes(router, CyberiaActionController, options);
16
16
  }
@@ -1,6 +1,6 @@
1
1
  import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
- import { loggerFactory } from '../../server/logger.js';
3
- import { DataQuery } from '../../server/data-query.js';
2
+ import { loggerFactory } from '../../server/ops/logger.js';
3
+ import { DataQuery } from '../../server/storage/data-query.js';
4
4
  import { DefaultCyberiaActions } from '../cyberia-server-defaults/cyberia-server-defaults.js';
5
5
 
6
6
  const logger = loggerFactory(import.meta);
@@ -34,10 +34,9 @@ class CyberiaActionService {
34
34
  if (!code) throw new Error('code parameter is required');
35
35
  const data = await CyberiaAction.findOne({ code }).lean();
36
36
  if (data) return data;
37
- // Fallback world delivers actions to the Go server from the canonical
38
- // defaults without persisting them; serve those so the client can fetch the
39
- // action's label + dialogue map by code. Quest OFFERS are NOT resolved here
40
- // the client locates offered quests via the cyberia-quest API by cell.
37
+ // The fallback world serves actions from the canonical defaults and never
38
+ // persists them. Serve the same defaults here, so the client can fetch an
39
+ // action by code. Quest offers come from the cyberia-quest API by cell.
41
40
  const fallback = DefaultCyberiaActions.find((a) => a.code === code);
42
41
  if (fallback) return fallback;
43
42
  throw new Error(`No action found for code: ${code}`);
@@ -0,0 +1,6 @@
1
+ import { buildCrudController } from '../../server/network/middlewares.js';
2
+ import { CyberiaAudioService } from './cyberia-audio.service.js';
3
+
4
+ const CyberiaAudioController = buildCrudController(CyberiaAudioService);
5
+
6
+ export { CyberiaAudioController };