cyberia 3.0.3 → 3.2.5

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 (296) hide show
  1. package/{.env.production → .env.example} +20 -4
  2. package/.github/workflows/engine-cyberia.cd.yml +43 -10
  3. package/.github/workflows/engine-cyberia.ci.yml +48 -26
  4. package/.github/workflows/ghpkg.ci.yml +5 -5
  5. package/.github/workflows/gitlab.ci.yml +1 -1
  6. package/.github/workflows/hardhat.ci.yml +82 -0
  7. package/.github/workflows/npmpkg.ci.yml +60 -14
  8. package/.github/workflows/publish.ci.yml +26 -7
  9. package/.github/workflows/publish.cyberia.ci.yml +5 -5
  10. package/.github/workflows/pwa-microservices-template-page.cd.yml +6 -7
  11. package/.github/workflows/pwa-microservices-template-test.ci.yml +4 -4
  12. package/.github/workflows/release.cd.yml +14 -8
  13. package/.vscode/extensions.json +9 -8
  14. package/.vscode/settings.json +3 -2
  15. package/CHANGELOG.md +643 -1
  16. package/CLI-HELP.md +132 -57
  17. package/Dockerfile +4 -2
  18. package/README.md +347 -22
  19. package/WHITE-PAPER.md +1540 -0
  20. package/bin/build.js +21 -12
  21. package/bin/cyberia.js +2640 -106
  22. package/bin/deploy.js +258 -372
  23. package/bin/file.js +5 -1
  24. package/bin/index.js +2640 -106
  25. package/bin/vs.js +3 -3
  26. package/conf.js +169 -105
  27. package/deployment.yaml +236 -20
  28. package/hardhat/.env.example +31 -0
  29. package/hardhat/README.md +531 -0
  30. package/hardhat/WHITE-PAPER.md +1540 -0
  31. package/hardhat/contracts/ObjectLayerToken.sol +391 -0
  32. package/hardhat/deployments/.gitkeep +0 -0
  33. package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
  34. package/hardhat/hardhat.config.js +136 -0
  35. package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
  36. package/hardhat/networks/besu-object-layer.network.json +138 -0
  37. package/hardhat/package-lock.json +4323 -0
  38. package/hardhat/package.json +36 -0
  39. package/hardhat/scripts/deployObjectLayerToken.js +98 -0
  40. package/hardhat/test/ObjectLayerToken.js +592 -0
  41. package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
  42. package/hardhat/types/ethers-contracts/common.ts +92 -0
  43. package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
  44. package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
  45. package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
  46. package/hardhat/types/ethers-contracts/index.ts +6 -0
  47. package/jsdoc.dd-cyberia.json +68 -0
  48. package/jsdoc.json +65 -49
  49. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +5 -4
  50. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +5 -4
  51. package/manifests/deployment/dd-cyberia-development/deployment.yaml +562 -0
  52. package/manifests/deployment/dd-cyberia-development/proxy.yaml +297 -0
  53. package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +132 -0
  54. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  55. package/manifests/deployment/dd-test-development/deployment.yaml +88 -74
  56. package/manifests/deployment/dd-test-development/proxy.yaml +13 -4
  57. package/manifests/deployment/playwright/deployment.yaml +1 -1
  58. package/manifests/pv-pvc-dd.yaml +1 -1
  59. package/nodemon.json +1 -1
  60. package/package.json +60 -48
  61. package/proxy.yaml +118 -10
  62. package/pv-pvc.yaml +132 -0
  63. package/scripts/k3s-node-setup.sh +1 -1
  64. package/scripts/ports-ls.sh +2 -0
  65. package/scripts/rhel-grpc-setup.sh +56 -0
  66. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +47 -1
  67. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +17 -2
  68. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
  69. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +80 -7
  70. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
  71. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
  72. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
  73. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
  74. package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
  75. package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
  76. package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
  77. package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
  78. package/src/api/cyberia-instance/cyberia-fallback-world.js +368 -0
  79. package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
  80. package/src/api/cyberia-instance/cyberia-instance.model.js +84 -0
  81. package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
  82. package/src/api/cyberia-instance/cyberia-instance.service.js +191 -0
  83. package/src/api/cyberia-instance/cyberia-portal-connector.js +486 -0
  84. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
  85. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +413 -0
  86. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +228 -0
  87. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
  88. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +42 -0
  89. package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
  90. package/src/api/cyberia-map/cyberia-map.model.js +30 -0
  91. package/src/api/cyberia-map/cyberia-map.router.js +40 -0
  92. package/src/api/cyberia-map/cyberia-map.service.js +74 -0
  93. package/src/api/document/document.service.js +1 -1
  94. package/src/api/file/file.controller.js +3 -1
  95. package/src/api/file/file.ref.json +18 -0
  96. package/src/api/file/file.service.js +28 -5
  97. package/src/api/ipfs/ipfs.controller.js +4 -25
  98. package/src/api/ipfs/ipfs.model.js +43 -34
  99. package/src/api/ipfs/ipfs.router.js +8 -13
  100. package/src/api/ipfs/ipfs.service.js +56 -104
  101. package/src/api/object-layer/README.md +347 -22
  102. package/src/api/object-layer/object-layer.controller.js +6 -2
  103. package/src/api/object-layer/object-layer.model.js +12 -8
  104. package/src/api/object-layer/object-layer.router.js +698 -42
  105. package/src/api/object-layer/object-layer.service.js +119 -37
  106. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +1 -2
  107. package/src/api/user/user.router.js +10 -5
  108. package/src/api/user/user.service.js +15 -14
  109. package/src/cli/baremetal.js +6 -10
  110. package/src/cli/cloud-init.js +0 -3
  111. package/src/cli/cluster.js +7 -7
  112. package/src/cli/db.js +723 -857
  113. package/src/cli/deploy.js +215 -105
  114. package/src/cli/env.js +34 -5
  115. package/src/cli/fs.js +5 -4
  116. package/src/cli/image.js +0 -3
  117. package/src/cli/index.js +83 -15
  118. package/src/cli/kubectl.js +211 -0
  119. package/src/cli/monitor.js +5 -6
  120. package/src/cli/release.js +284 -0
  121. package/src/cli/repository.js +708 -62
  122. package/src/cli/run.js +371 -151
  123. package/src/cli/secrets.js +73 -2
  124. package/src/cli/ssh.js +1 -1
  125. package/src/cli/test.js +3 -3
  126. package/src/client/Cryptokoyn.index.js +3 -4
  127. package/src/client/CyberiaPortal.index.js +3 -4
  128. package/src/client/Default.index.js +3 -4
  129. package/src/client/Itemledger.index.js +4 -963
  130. package/src/client/Underpost.index.js +3 -4
  131. package/src/client/components/core/AgGrid.js +20 -5
  132. package/src/client/components/core/Alert.js +2 -2
  133. package/src/client/components/core/AppStore.js +69 -0
  134. package/src/client/components/core/CalendarCore.js +2 -2
  135. package/src/client/components/core/Content.js +22 -3
  136. package/src/client/components/core/Docs.js +30 -6
  137. package/src/client/components/core/DropDown.js +137 -17
  138. package/src/client/components/core/FileExplorer.js +71 -4
  139. package/src/client/components/core/Input.js +1 -1
  140. package/src/client/components/core/Keyboard.js +2 -2
  141. package/src/client/components/core/LogIn.js +2 -2
  142. package/src/client/components/core/LogOut.js +2 -2
  143. package/src/client/components/core/Modal.js +20 -7
  144. package/src/client/components/core/Panel.js +0 -1
  145. package/src/client/components/core/PanelForm.js +19 -19
  146. package/src/client/components/core/RichText.js +1 -2
  147. package/src/client/components/core/SocketIo.js +82 -29
  148. package/src/client/components/core/SocketIoHandler.js +75 -0
  149. package/src/client/components/core/Stream.js +143 -95
  150. package/src/client/components/core/Webhook.js +40 -7
  151. package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
  152. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +3 -3
  153. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +2 -2
  154. package/src/client/components/cryptokoyn/MenuCryptokoyn.js +3 -3
  155. package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
  156. package/src/client/components/cyberia/InstanceEngineCyberia.js +700 -0
  157. package/src/client/components/cyberia/MapEngineCyberia.js +1359 -2
  158. package/src/client/components/cyberia/ObjectLayerEngineModal.js +17 -6
  159. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +92 -54
  160. package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
  161. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +217 -30
  162. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +44 -2
  163. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +3 -4
  164. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +2 -2
  165. package/src/client/components/cyberia-portal/MenuCyberiaPortal.js +104 -9
  166. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +5 -0
  167. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
  168. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
  169. package/src/client/components/default/AppStoreDefault.js +5 -0
  170. package/src/client/components/default/LogInDefault.js +3 -3
  171. package/src/client/components/default/LogOutDefault.js +2 -2
  172. package/src/client/components/default/MenuDefault.js +5 -5
  173. package/src/client/components/default/SocketIoDefault.js +3 -51
  174. package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
  175. package/src/client/components/itemledger/LogInItemledger.js +3 -3
  176. package/src/client/components/itemledger/LogOutItemledger.js +2 -2
  177. package/src/client/components/itemledger/MenuItemledger.js +3 -3
  178. package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
  179. package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
  180. package/src/client/components/underpost/CssUnderpost.js +59 -0
  181. package/src/client/components/underpost/LogInUnderpost.js +6 -3
  182. package/src/client/components/underpost/LogOutUnderpost.js +4 -2
  183. package/src/client/components/underpost/MenuUnderpost.js +104 -18
  184. package/src/client/components/underpost/RoutesUnderpost.js +2 -0
  185. package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
  186. package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
  187. package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
  188. package/src/client/public/cryptokoyn/microdata.json +85 -0
  189. package/src/client/public/cryptokoyn/site.webmanifest +57 -0
  190. package/src/client/public/cryptokoyn/sitemap +3 -3
  191. package/src/client/public/default/sitemap +3 -3
  192. package/src/client/public/itemledger/browserconfig.xml +2 -2
  193. package/src/client/public/itemledger/manifest.webmanifest +4 -4
  194. package/src/client/public/itemledger/microdata.json +71 -0
  195. package/src/client/public/itemledger/sitemap +3 -3
  196. package/src/client/public/itemledger/yandex-browser-manifest.json +2 -2
  197. package/src/client/public/test/sitemap +3 -3
  198. package/src/client/services/core/core.service.js +20 -8
  199. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +105 -0
  200. package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
  201. package/src/client/services/cyberia-entity/cyberia-entity.service.js +105 -0
  202. package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
  203. package/src/client/services/cyberia-instance/cyberia-instance.service.js +122 -0
  204. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +105 -0
  205. package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
  206. package/src/client/services/cyberia-map/cyberia-map.service.js +126 -0
  207. package/src/client/services/instance/instance.management.js +2 -2
  208. package/src/client/services/ipfs/ipfs.service.js +3 -23
  209. package/src/client/services/object-layer/object-layer.management.js +3 -3
  210. package/src/client/services/object-layer/object-layer.service.js +21 -0
  211. package/src/client/services/user/user.management.js +2 -2
  212. package/src/client/ssr/body/404.js +15 -11
  213. package/src/client/ssr/body/500.js +15 -11
  214. package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
  215. package/src/client/ssr/head/PwaItemledger.js +60 -0
  216. package/src/client/ssr/offline/NoNetworkConnection.js +11 -10
  217. package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
  218. package/src/client/ssr/pages/Test.js +11 -10
  219. package/src/client.build.js +0 -3
  220. package/src/client.dev.js +0 -3
  221. package/src/db/DataBaseProvider.js +17 -2
  222. package/src/db/mariadb/MariaDB.js +14 -9
  223. package/src/db/mongo/MongooseDB.js +17 -1
  224. package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +305 -0
  225. package/src/grpc/cyberia/README.md +326 -0
  226. package/src/grpc/cyberia/grpc-server.js +530 -0
  227. package/src/index.js +24 -1
  228. package/src/proxy.js +0 -3
  229. package/src/runtime/express/Dockerfile +4 -0
  230. package/src/runtime/express/Express.js +33 -10
  231. package/src/runtime/lampp/Dockerfile +13 -2
  232. package/src/runtime/lampp/Lampp.js +33 -17
  233. package/src/runtime/wp/Dockerfile +68 -0
  234. package/src/runtime/wp/Wp.js +639 -0
  235. package/src/server/auth.js +36 -15
  236. package/src/server/backup.js +39 -12
  237. package/src/server/besu-genesis-generator.js +1630 -0
  238. package/src/server/client-build-docs.js +133 -17
  239. package/src/server/client-build-live.js +9 -18
  240. package/src/server/client-build.js +229 -101
  241. package/src/server/client-dev-server.js +14 -13
  242. package/src/server/client-formatted.js +109 -57
  243. package/src/server/conf.js +391 -164
  244. package/src/server/cron.js +27 -24
  245. package/src/server/dns.js +29 -12
  246. package/src/server/downloader.js +0 -2
  247. package/src/server/ipfs-client.js +24 -1
  248. package/src/server/logger.js +27 -9
  249. package/src/server/object-layer.js +217 -103
  250. package/src/server/peer.js +8 -2
  251. package/src/server/process.js +1 -50
  252. package/src/server/proxy.js +4 -8
  253. package/src/server/runtime.js +30 -9
  254. package/src/server/semantic-layer-generator-floor.js +359 -0
  255. package/src/server/semantic-layer-generator-skin.js +1294 -0
  256. package/src/server/semantic-layer-generator.js +116 -555
  257. package/src/server/ssr.js +0 -3
  258. package/src/server/start.js +19 -12
  259. package/src/server/tls.js +0 -2
  260. package/src/server.js +0 -4
  261. package/src/ws/IoInterface.js +1 -10
  262. package/src/ws/IoServer.js +14 -33
  263. package/src/ws/core/channels/core.ws.chat.js +65 -20
  264. package/src/ws/core/channels/core.ws.mailer.js +113 -32
  265. package/src/ws/core/channels/core.ws.stream.js +90 -31
  266. package/src/ws/core/core.ws.connection.js +12 -33
  267. package/src/ws/core/core.ws.emit.js +10 -26
  268. package/src/ws/core/core.ws.server.js +25 -58
  269. package/src/ws/default/channels/default.ws.main.js +53 -12
  270. package/src/ws/default/default.ws.connection.js +26 -13
  271. package/src/ws/default/default.ws.server.js +30 -12
  272. package/.env.development +0 -43
  273. package/.env.test +0 -43
  274. package/hardhat/contracts/CryptoKoyn.sol +0 -59
  275. package/hardhat/contracts/ItemLedger.sol +0 -73
  276. package/hardhat/contracts/Lock.sol +0 -34
  277. package/hardhat/hardhat.config.cjs +0 -45
  278. package/hardhat/ignition/modules/Lock.js +0 -18
  279. package/hardhat/networks/cryptokoyn-itemledger.network.json +0 -29
  280. package/hardhat/scripts/deployCryptokoyn.cjs +0 -25
  281. package/hardhat/scripts/deployItemledger.cjs +0 -25
  282. package/hardhat/test/Lock.js +0 -126
  283. package/hardhat/white-paper.md +0 -581
  284. package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
  285. package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
  286. package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
  287. package/src/client/components/default/ElementsDefault.js +0 -38
  288. package/src/client/components/itemledger/CommonItemledger.js +0 -29
  289. package/src/client/components/itemledger/ElementsItemledger.js +0 -38
  290. package/src/client/components/underpost/CommonUnderpost.js +0 -29
  291. package/src/client/components/underpost/ElementsUnderpost.js +0 -38
  292. package/src/ws/core/management/core.ws.chat.js +0 -8
  293. package/src/ws/core/management/core.ws.mailer.js +0 -16
  294. package/src/ws/core/management/core.ws.stream.js +0 -8
  295. package/src/ws/default/management/default.ws.main.js +0 -8
  296. package/white-paper.md +0 -581
@@ -544,10 +544,13 @@ const FileExplorer = {
544
544
  this.eGui = document.createElement('div');
545
545
  const isPublic = params.data.isPublic;
546
546
  const toggleId = `toggle-public-${params.data._id}`;
547
+ const hasGenericFile = !!params.data.hasGenericFile;
548
+ const hasMdFile = !!params.data.hasMdFile;
549
+
547
550
  this.eGui.innerHTML = html`
548
551
  <div class="fl">
549
552
  ${await BtnIcon.Render({
550
- class: `in fll management-table-btn-mini btn-file-download-${params.data._id}`,
553
+ class: `in fll management-table-btn-mini btn-file-download-${params.data._id}${!hasGenericFile ? ' btn-disabled' : ''}`,
551
554
  label: html` <i class="fas fa-download"></i>`,
552
555
  type: 'button',
553
556
  })}
@@ -562,10 +565,15 @@ const FileExplorer = {
562
565
  type: 'button',
563
566
  })}
564
567
  ${await BtnIcon.Render({
565
- class: `in fll management-table-btn-mini btn-file-copy-content-link-${params.data._id}`,
568
+ class: `in fll management-table-btn-mini btn-file-copy-content-link-${params.data._id}${!hasGenericFile ? ' btn-disabled' : ''}`,
566
569
  label: html`<i class="fas fa-copy"></i>`,
567
570
  type: 'button',
568
571
  })}
572
+ ${await BtnIcon.Render({
573
+ class: `in fll management-table-btn-mini btn-file-copy-md-link-${params.data._id}${!hasMdFile ? ' btn-disabled' : ''}`,
574
+ label: html`<i class="fas fa-file-code"></i>`,
575
+ type: 'button',
576
+ })}
569
577
  ${await BtnIcon.Render({
570
578
  class: `in fll management-table-btn-mini btn-file-edit-${params.data._id}`,
571
579
  label: html`<i class="fas fa-edit"></i>`,
@@ -591,11 +599,46 @@ const FileExplorer = {
591
599
  ? getApiBaseUrl({ id: originObj.fileId._id, endpoint: 'file/blob' })
592
600
  : undefined;
593
601
 
602
+ const mdBlobUri =
603
+ originObj && originObj.mdFileId
604
+ ? getApiBaseUrl({ id: originObj.mdFileId._id, endpoint: 'file/blob' })
605
+ : undefined;
606
+
594
607
  if (!originObj) {
595
608
  s(`.btn-file-view-${params.data._id}`).classList.add('hide');
596
609
  s(`.btn-file-copy-content-link-${params.data._id}`).classList.add('hide');
597
610
  }
598
611
 
612
+ // Disable download button if no generic file
613
+ if (!hasGenericFile) {
614
+ const dlBtn = s(`.btn-file-download-${params.data._id}`);
615
+ if (dlBtn) {
616
+ dlBtn.style.opacity = '0.4';
617
+ dlBtn.style.cursor = 'not-allowed';
618
+ dlBtn.style.pointerEvents = 'none';
619
+ }
620
+ }
621
+
622
+ // Disable copy generic file link button if no generic file
623
+ if (!hasGenericFile) {
624
+ const copyBtn = s(`.btn-file-copy-content-link-${params.data._id}`);
625
+ if (copyBtn) {
626
+ copyBtn.style.opacity = '0.4';
627
+ copyBtn.style.cursor = 'not-allowed';
628
+ copyBtn.style.pointerEvents = 'none';
629
+ }
630
+ }
631
+
632
+ // Disable copy md file link button if no md file
633
+ if (!hasMdFile) {
634
+ const mdCopyBtn = s(`.btn-file-copy-md-link-${params.data._id}`);
635
+ if (mdCopyBtn) {
636
+ mdCopyBtn.style.opacity = '0.4';
637
+ mdCopyBtn.style.cursor = 'not-allowed';
638
+ mdCopyBtn.style.pointerEvents = 'none';
639
+ }
640
+ }
641
+
599
642
  EventsUI.onClick(`.btn-file-view-${params.data._id}`, async (e) => {
600
643
  e.preventDefault();
601
644
  if (location.href !== url) {
@@ -606,6 +649,7 @@ const FileExplorer = {
606
649
 
607
650
  EventsUI.onClick(`.btn-file-copy-content-link-${params.data._id}`, async (e) => {
608
651
  e.preventDefault();
652
+ if (!hasGenericFile || !blobUri) return;
609
653
  await copyData(blobUri);
610
654
  NotificationManager.Push({
611
655
  html: Translate.Render('success-copy-data'),
@@ -613,10 +657,21 @@ const FileExplorer = {
613
657
  });
614
658
  });
615
659
 
660
+ EventsUI.onClick(`.btn-file-copy-md-link-${params.data._id}`, async (e) => {
661
+ e.preventDefault();
662
+ if (!hasMdFile || !mdBlobUri) return;
663
+ await copyData(mdBlobUri);
664
+ NotificationManager.Push({
665
+ html: Translate.Render('success-copy-data'),
666
+ status: 'success',
667
+ });
668
+ });
669
+
616
670
  EventsUI.onClick(`.btn-file-download-${params.data._id}`, async (e) => {
617
671
  e.preventDefault();
672
+ if (!hasGenericFile) return;
618
673
  try {
619
- // Use FileService with blob/ prefix for centralized blob fetching
674
+ // Use FileService with blob/ prefix for blob fetching
620
675
  const { data: blobArray, status } = await FileService.get({ id: `blob/${params.data.fileId}` });
621
676
  if (status === 'success' && blobArray && blobArray[0]) {
622
677
  downloadFile(blobArray[0], params.data.name);
@@ -721,6 +776,12 @@ const FileExplorer = {
721
776
  documentInstance[docIndex].isPublic = data.isPublic;
722
777
  }
723
778
 
779
+ // Refresh the isPublic column cell in the grid
780
+ const rowNode = AgGrid.grids[gridFileId].getRowNode(params.node.id);
781
+ if (rowNode) {
782
+ rowNode.setDataValue('isPublic', data.isPublic);
783
+ }
784
+
724
785
  // Update button icon
725
786
  const btnElement = s(`.${toggleId}`);
726
787
  if (btnElement) {
@@ -1347,7 +1408,13 @@ const FileExplorer = {
1347
1408
  { field: 'name', flex: 2, headerName: 'Title', cellRenderer: LoadFileNameRenderer },
1348
1409
  { field: 'mdFileName', flex: 1, headerName: 'MD File Name' },
1349
1410
  { field: 'fileName', flex: 1, headerName: 'Generic File Name' },
1350
- { headerName: '', width: 150, cellRenderer: LoadFileActionsRenderer },
1411
+ {
1412
+ field: 'isPublic',
1413
+ headerName: 'Public',
1414
+ width: 90,
1415
+ cellDataType: 'boolean',
1416
+ },
1417
+ { headerName: '', width: 180, cellRenderer: LoadFileActionsRenderer },
1351
1418
  ],
1352
1419
  },
1353
1420
  })}
@@ -101,7 +101,7 @@ const getFileFromFileData = (fileData) => {
101
101
  /**
102
102
  * Fetch file content from blob endpoint and create File object.
103
103
  * Used for metadata-only format files during edit mode.
104
- * Uses FileService with blob/ prefix for centralized blob fetching.
104
+ * Uses FileService with blob/ prefix for blob fetching.
105
105
  *
106
106
  * @async
107
107
  * @function getFileFromBlobEndpoint
@@ -3,8 +3,8 @@ import { cap, getId } from './CommonJs.js';
3
3
  const Keyboard = {
4
4
  ActiveKey: {},
5
5
  Event: {},
6
- Init: async function (options = { callBackTime: 50 }) {
7
- const { callBackTime } = options;
6
+ Init: async function () {
7
+ const callBackTime = 45;
8
8
  window.onkeydown = (e = new KeyboardEvent()) => {
9
9
  this.ActiveKey[e.key] = true;
10
10
  // e.composedPath()
@@ -10,7 +10,7 @@ import { NotificationManager } from './NotificationManager.js';
10
10
  import { Translate } from './Translate.js';
11
11
  import { Validator } from './Validator.js';
12
12
  import { htmls, s } from './VanillaJs.js';
13
- import { Webhook } from './Webhook.js';
13
+ import { WebhookProvider } from './Webhook.js';
14
14
 
15
15
  const logger = loggerFactory(import.meta);
16
16
 
@@ -31,7 +31,7 @@ const LogIn = {
31
31
 
32
32
  for (const eventKey of Object.keys(this.Event)) await this.Event[eventKey](options);
33
33
  if (!user || user.role === 'guest') return;
34
- await Webhook.register({ user });
34
+ await WebhookProvider.register({ user });
35
35
  if (s(`.session`))
36
36
  htmls(
37
37
  `.session`,
@@ -3,13 +3,13 @@ import { BtnIcon } from './BtnIcon.js';
3
3
  import { LogIn } from './LogIn.js';
4
4
  import { Translate } from './Translate.js';
5
5
  import { htmls, s } from './VanillaJs.js';
6
- import { Webhook } from './Webhook.js';
6
+ import { WebhookProvider } from './Webhook.js';
7
7
  import { NotificationManager } from './NotificationManager.js';
8
8
 
9
9
  const LogOut = {
10
10
  Event: {},
11
11
  Trigger: async function (options) {
12
- await Webhook.unregister();
12
+ await WebhookProvider.unregister();
13
13
  for (const eventKey of Object.keys(this.Event)) await this.Event[eventKey](options);
14
14
  if (s(`.session`))
15
15
  htmls(
@@ -1357,7 +1357,6 @@ const Modal = {
1357
1357
  class: 'hide',
1358
1358
  style: {
1359
1359
  // overflow: 'hidden',
1360
- background: 'none',
1361
1360
  resize: 'none',
1362
1361
  'min-width': `${minWidth}px`,
1363
1362
  'z-index': 5,
@@ -2424,20 +2423,34 @@ const Modal = {
2424
2423
  },
2425
2424
  };
2426
2425
 
2427
- const renderMenuLabel = ({ img, text, icon }) => {
2428
- if (!img) return html`<span class="inl menu-btn-icon">${icon}</span> ${text}`;
2429
- return html`<img class="abs center img-btn-square-menu" src="${getProxyPath()}assets/ui-icons/${img}" />
2426
+ const renderMenuLabel = ({ img, src, text, icon }) => {
2427
+ if (!img && !src) return html`<span class="inl menu-btn-icon">${icon}</span> ${text}`;
2428
+ const imgSrc = src ? src : `${getProxyPath()}assets/ui-icons/${img}`;
2429
+ return html`<img class="abs center img-btn-square-menu" src="${imgSrc}" />
2430
2430
  <div class="abs center main-btn-menu-text">${text}</div>`;
2431
2431
  };
2432
2432
 
2433
2433
  const renderViewTitle = (
2434
- options = { icon: '', img: '', text: '', assetFolder: '', 'ui-icons': '', dim, top, topText: '' },
2434
+ options = {
2435
+ icon: '',
2436
+ img: '',
2437
+ text: '',
2438
+ assetFolder: '',
2439
+ 'ui-icon': '',
2440
+ imgClass: '',
2441
+ textClass: '',
2442
+ dim,
2443
+ top,
2444
+ topText: '',
2445
+ },
2435
2446
  ) => {
2436
2447
  if (options.dim === undefined) options.dim = 30;
2437
2448
  const { img, text, icon, dim, top } = options;
2438
2449
  if (!img && !options['ui-icon']) return html`<span class="view-title-icon">${icon}</span> ${text}`;
2450
+ const imgClass = options.imgClass || 'abs img-btn-square-view-title';
2451
+ const textClass = options.textClass || 'in text-btn-square-view-title';
2439
2452
  return html`<img
2440
- class="abs img-btn-square-view-title"
2453
+ class="${imgClass}"
2441
2454
  style="${renderCssAttr({
2442
2455
  style: {
2443
2456
  width: `${dim}px`,
@@ -2450,7 +2463,7 @@ const renderViewTitle = (
2450
2463
  : img}"
2451
2464
  />
2452
2465
  <div
2453
- class="in text-btn-square-view-title"
2466
+ class="${textClass}"
2454
2467
  style="${renderCssAttr({
2455
2468
  style: {
2456
2469
  // 'padding-left': `${20 + dim}px`,
@@ -453,7 +453,6 @@ const Panel = {
453
453
 
454
454
  tagRender += await Badge.Render({
455
455
  text: tag,
456
- style: { color: tagColor },
457
456
  classList: 'inl panel-tag-clickable',
458
457
  style: {
459
458
  margin: '3px',
@@ -85,7 +85,7 @@ const PanelForm = {
85
85
  options = {
86
86
  idPanel: '',
87
87
  defaultUrlImage: '',
88
- Elements: {},
88
+ appStore: {},
89
89
  parentIdModal: undefined,
90
90
  route: 'home',
91
91
  htmlFormHeader: async () => '',
@@ -97,7 +97,7 @@ const PanelForm = {
97
97
  showCreatorProfile: false,
98
98
  },
99
99
  ) {
100
- const { idPanel, defaultUrlImage, Elements } = options;
100
+ const { idPanel, defaultUrlImage, appStore } = options;
101
101
 
102
102
  // Authenticated users don't need 'public' tag - they see all their own posts
103
103
  // Only include 'public' for unauthenticated users (handled by backend)
@@ -458,10 +458,10 @@ const PanelForm = {
458
458
  baseNewDoc.mdFileId = hasMdContent
459
459
  ? `<div class="markdown-content">${marked.parse(data.mdFileId)}</div>`
460
460
  : null;
461
- baseNewDoc.userId = Elements.Data.user?.main?.model?.user?._id;
461
+ baseNewDoc.userId = appStore.Data.user?.main?.model?.user?._id;
462
462
 
463
463
  // Ensure profileImageId is properly formatted as object with _id property
464
- const profileImageIdValue = Elements.Data.user?.main?.model?.user?.profileImageId;
464
+ const profileImageIdValue = appStore.Data.user?.main?.model?.user?.profileImageId;
465
465
  const formattedProfileImageId = profileImageIdValue
466
466
  ? typeof profileImageIdValue === 'string'
467
467
  ? { _id: profileImageIdValue }
@@ -469,9 +469,9 @@ const PanelForm = {
469
469
  : null;
470
470
 
471
471
  baseNewDoc.userInfo = {
472
- username: Elements.Data.user?.main?.model?.user?.username,
473
- email: Elements.Data.user?.main?.model?.user?.email,
474
- _id: Elements.Data.user?.main?.model?.user?._id,
472
+ username: appStore.Data.user?.main?.model?.user?.username,
473
+ email: appStore.Data.user?.main?.model?.user?.email,
474
+ _id: appStore.Data.user?.main?.model?.user?._id,
475
475
  profileImageId: formattedProfileImageId,
476
476
  };
477
477
  baseNewDoc.tools = true;
@@ -737,8 +737,8 @@ const PanelForm = {
737
737
  tools:
738
738
  documentObject.userId &&
739
739
  typeof documentObject.userId === 'object' &&
740
- Elements.Data.user?.main?.model?.user?._id &&
741
- documentObject.userId._id === Elements.Data.user.main.model.user._id,
740
+ appStore.Data.user?.main?.model?.user?._id &&
741
+ documentObject.userId._id === appStore.Data.user.main.model.user._id,
742
742
  _id: documentObject._id,
743
743
  totalCopyShareLinkCount: documentObject.totalCopyShareLinkCount || 0,
744
744
  isPublic: documentObject.isPublic || false,
@@ -772,8 +772,8 @@ const PanelForm = {
772
772
  tools:
773
773
  documentObject.userId &&
774
774
  typeof documentObject.userId === 'object' &&
775
- Elements.Data.user?.main?.model?.user?._id &&
776
- documentObject.userId._id === Elements.Data.user.main.model.user._id,
775
+ appStore.Data.user?.main?.model?.user?._id &&
776
+ documentObject.userId._id === appStore.Data.user.main.model.user._id,
777
777
  _id: documentObject._id,
778
778
  totalCopyShareLinkCount: documentObject.totalCopyShareLinkCount || 0,
779
779
  isPublic: documentObject.isPublic || false,
@@ -867,10 +867,10 @@ const PanelForm = {
867
867
  try {
868
868
  const cid = getQueryParams().cid ? getQueryParams().cid : '';
869
869
  const forceUpdate =
870
- Elements.Data.user.main.model &&
871
- Elements.Data.user.main.model.user &&
872
- Elements.Data.user.main.model.user._id &&
873
- lastUserId !== Elements.Data.user.main.model.user._id;
870
+ appStore.Data.user.main.model &&
871
+ appStore.Data.user.main.model.user &&
872
+ appStore.Data.user.main.model.user._id &&
873
+ lastUserId !== appStore.Data.user.main.model.user._id;
874
874
 
875
875
  logger.warn(
876
876
  {
@@ -878,8 +878,8 @@ const PanelForm = {
878
878
  cid,
879
879
  forceUpdate,
880
880
  },
881
- Elements.Data.user?.main?.model?.user
882
- ? JSON.stringify(Elements.Data.user.main.model.user, null, 4)
881
+ appStore.Data.user?.main?.model?.user
882
+ ? JSON.stringify(appStore.Data.user.main.model.user, null, 4)
883
883
  : 'No user data',
884
884
  );
885
885
 
@@ -889,8 +889,8 @@ const PanelForm = {
889
889
 
890
890
  if (loadingGetData || (normalizedLastCid === normalizedCid && !forceUpdate)) return;
891
891
  loadingGetData = true;
892
- lastUserId = Elements.Data.user?.main?.model?.user?._id
893
- ? newInstance(Elements.Data.user.main.model.user._id)
892
+ lastUserId = appStore.Data.user?.main?.model?.user?._id
893
+ ? newInstance(appStore.Data.user.main.model.user._id)
894
894
  : null;
895
895
  lastCid = cid;
896
896
 
@@ -30,10 +30,9 @@ const RichText = {
30
30
  return html` <style>
31
31
  .md-container {
32
32
  background: white;
33
- color: black;
34
33
  }
35
34
  .md-container button {
36
- color: black !important;
35
+ color: black;
37
36
  }
38
37
  </style>
39
38
  <div class="in md-container"><textarea class="${id}"></textarea></div>`;
@@ -1,25 +1,81 @@
1
+ /**
2
+ * Client-side WebSocket provider using Socket.IO.
3
+ * Manages a singleton socket connection, channel registration, and event dispatching.
4
+ *
5
+ * @module client/core/SocketIo
6
+ * @namespace SocketIoProvider
7
+ */
1
8
  import { io } from 'socket.io/client-dist/socket.io.esm.min.js';
2
9
  import { loggerFactory } from './Logger.js';
3
10
  import { getWsBasePath, getWsBaseUrl } from '../../services/core/core.service.js';
4
11
 
5
12
  const logger = loggerFactory(import.meta);
6
13
 
7
- const SocketIo = {
8
- Event: {
14
+ /**
15
+ * @class SocketIoProvider
16
+ * @classdesc Provides static methods for managing a singleton Socket.IO client connection,
17
+ * channel event dispatching, and message emission.
18
+ * @memberof SocketIoProvider
19
+ */
20
+ class SocketIoProvider {
21
+ /**
22
+ * Event callback registry, keyed by channel name → unique callback ID → handler function.
23
+ * Built-in channels: `connect`, `connect_error`, `disconnect`.
24
+ *
25
+ * @static
26
+ * @type {Object.<string, Object.<string, function>>}
27
+ */
28
+ static Event = {
9
29
  connect: {},
10
30
  connect_error: {},
11
31
  disconnect: {},
12
- },
13
- /** @type {import('socket.io').Socket} */
14
- socket: null,
15
- Emit: function (channel = '', payload = {}) {
32
+ };
33
+
34
+ /**
35
+ * The active Socket.IO client socket instance.
36
+ *
37
+ * @static
38
+ * @type {import('socket.io-client').Socket|null}
39
+ */
40
+ static socket = null;
41
+
42
+ /**
43
+ * The current WebSocket host URL.
44
+ *
45
+ * @static
46
+ * @type {string|undefined}
47
+ */
48
+ static host;
49
+
50
+ /**
51
+ * Emits a JSON-serialized payload to the server on the specified channel.
52
+ *
53
+ * @static
54
+ * @param {string} [channel=''] - The channel/event name to emit on.
55
+ * @param {Object} [payload={}] - The data to send.
56
+ * @returns {void}
57
+ */
58
+ static Emit(channel = '', payload = {}) {
16
59
  try {
17
60
  this.socket.emit(channel, JSON.stringify(payload));
18
61
  } catch (error) {
19
62
  logger.error(error);
20
63
  }
21
- },
22
- Init: async function (options) {
64
+ }
65
+
66
+ /**
67
+ * Initializes (or re-initializes) the Socket.IO connection.
68
+ * Disconnects any existing socket, creates a new connection, and registers
69
+ * built-in event listeners and custom channels.
70
+ *
71
+ * @static
72
+ * @async
73
+ * @param {Object} options - Connection options.
74
+ * @param {string} [options.host] - Override WebSocket host URL.
75
+ * @param {Object.<string, Object>} [options.channels] - Channel definitions to register listeners for.
76
+ * @returns {Promise<void>}
77
+ */
78
+ static async Init(options) {
23
79
  if (this.socket) this.socket.disconnect();
24
80
  const path = getWsBasePath();
25
81
  this.host = options.host ? options.host : getWsBaseUrl({ wsBasePath: '' });
@@ -29,24 +85,10 @@ const SocketIo = {
29
85
  });
30
86
  const connectOptions = {
31
87
  path: path === '/' ? undefined : path,
32
- // auth: {
33
- // token: '',
34
- // },
35
- // query: {
36
- // 'my-key': 'my-value',
37
- // },
38
- // forceNew: true,
39
- // reconnectionAttempts: 'Infinity',
40
- // timeout: 10000,
41
- // autoConnect: 5000,
42
- // Custom auth socket io credentials:
43
88
  withCredentials: true,
44
- extraHeaders: {
45
- // "my-custom-header": "abcd"
46
- },
89
+ extraHeaders: {},
47
90
  transports: ['websocket', 'polling', 'flashsocket'],
48
91
  };
49
- // logger.error(`connect options:`, JSON.stringify(connectOptions, null, 4));
50
92
  this.socket = io(this.host, connectOptions);
51
93
 
52
94
  this.socket.on('connect', () => {
@@ -65,17 +107,28 @@ const SocketIo = {
65
107
  });
66
108
 
67
109
  if (options && 'channels' in options) this.setChannels(options.channels);
68
- },
69
- setChannels: function (channels) {
110
+ }
111
+
112
+ /**
113
+ * Registers socket listeners for each channel key, routing incoming messages
114
+ * to all registered callbacks in `Event[channel]`.
115
+ *
116
+ * @static
117
+ * @param {Object.<string, Object>} channels - Channel definitions keyed by channel name.
118
+ * @returns {void}
119
+ */
120
+ static setChannels(channels) {
70
121
  Object.keys(channels).map((type) => {
71
122
  logger.info(`load chanel`, type);
72
123
  this.Event[type] = {};
73
124
  this.socket.on(type, (...args) => {
74
- // logger.info(`event: ${type} | ${JSON.stringify(args, null, 4)}`);
75
125
  Object.keys(this.Event[type]).map((keyEvent) => this.Event[type][keyEvent](args));
76
126
  });
77
127
  });
78
- },
79
- };
128
+ }
129
+ }
130
+
131
+ /** @type {SocketIoProvider} Backward compatibility alias. */
132
+ const SocketIo = SocketIoProvider;
80
133
 
81
- export { SocketIo };
134
+ export { SocketIoProvider, SocketIo };
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Shared factory for app-specific WebSocket event handlers.
3
+ * Eliminates duplication across per-app SocketIo*.js modules by providing
4
+ * common channel event handling (chat, email-confirmed, etc.).
5
+ *
6
+ * @module client/core/SocketIoHandler
7
+ * @namespace SocketIoHandlerProvider
8
+ */
9
+ import { Account } from './Account.js';
10
+ import { Chat } from './Chat.js';
11
+ import { s4 } from './CommonJs.js';
12
+ import { loggerFactory } from './Logger.js';
13
+ import { SocketIo } from './SocketIo.js';
14
+ import { s } from './VanillaJs.js';
15
+
16
+ const logger = loggerFactory(import.meta);
17
+
18
+ /**
19
+ * @class SocketIoHandlerProvider
20
+ * @classdesc Provides a static factory method to create app-specific SocketIo event handlers
21
+ * from an {@link AppStore} instance. Handles common channel events (chat, email-confirmed)
22
+ * and wires connect/disconnect lifecycle.
23
+ * @memberof SocketIoHandlerProvider
24
+ */
25
+ class SocketIoHandlerProvider {
26
+ /**
27
+ * Creates a standard SocketIo event initialization object for an app module.
28
+ *
29
+ * @static
30
+ * @param {import('./AppStore.js').AppStore} appStore - The app-specific AppStore instance.
31
+ * @returns {{ Init: function(): Promise<void> }} An object with an `Init` method for SocketIo event registration.
32
+ */
33
+ static create(appStore) {
34
+ return {
35
+ Init() {
36
+ return new Promise((resolve) => {
37
+ for (const type of Object.keys(appStore.Data)) {
38
+ SocketIo.Event[type][s4()] = async (args) => {
39
+ args = JSON.parse(args[0]);
40
+ switch (type) {
41
+ case 'chat':
42
+ {
43
+ const idModal = 'modal-chat';
44
+ if (s(`.${idModal}-chat-box`)) Chat.appendChatBox({ idModal, ...args });
45
+ }
46
+ break;
47
+
48
+ default:
49
+ break;
50
+ }
51
+ const { status } = args;
52
+
53
+ switch (status) {
54
+ case 'email-confirmed': {
55
+ const newUser = { ...appStore.Data.user.main.model.user, emailConfirmed: true };
56
+ Account.renderVerifyEmailStatus(newUser);
57
+ Account.triggerUpdateEvent({ user: newUser });
58
+ break;
59
+ }
60
+
61
+ default:
62
+ break;
63
+ }
64
+ };
65
+ }
66
+ SocketIo.Event.connect[s4()] = async (reason) => {};
67
+ SocketIo.Event.disconnect[s4()] = async (reason) => {};
68
+ return resolve();
69
+ });
70
+ },
71
+ };
72
+ }
73
+ }
74
+
75
+ export { SocketIoHandlerProvider };