cyberia 3.1.3 → 3.2.9
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.
- package/.env.example +0 -2
- package/.github/workflows/engine-cyberia.cd.yml +10 -8
- package/.github/workflows/engine-cyberia.ci.yml +12 -29
- package/.github/workflows/ghpkg.ci.yml +4 -4
- package/.github/workflows/npmpkg.ci.yml +28 -11
- package/.github/workflows/publish.ci.yml +21 -2
- package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -5
- package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
- package/.github/workflows/release.cd.yml +14 -10
- package/CHANGELOG.md +783 -1
- package/CLI-HELP.md +95 -18
- package/Dockerfile +0 -2
- package/README.md +290 -220
- package/bin/build.js +24 -7
- package/bin/cyberia.js +2838 -252
- package/bin/deploy.js +747 -125
- package/bin/file.js +9 -0
- package/bin/index.js +2838 -252
- package/bin/vs.js +1 -1
- package/conf.js +99 -65
- package/deployment.yaml +18 -164
- package/hardhat/hardhat.config.js +13 -13
- package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
- package/hardhat/package-lock.json +2559 -5864
- package/hardhat/package.json +14 -23
- package/hardhat/scripts/deployObjectLayerToken.js +1 -1
- package/hardhat/test/ObjectLayerToken.js +4 -2
- package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
- package/hardhat/types/ethers-contracts/common.ts +92 -0
- package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
- package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
- package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
- package/hardhat/types/ethers-contracts/index.ts +6 -0
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +6 -5
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +6 -5
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +18 -164
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +7 -79
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +112 -28
- package/manifests/deployment/dd-test-development/proxy.yaml +46 -1
- package/manifests/deployment/playwright/deployment.yaml +1 -1
- package/nodemon.json +1 -1
- package/package.json +39 -24
- package/proxy.yaml +7 -79
- package/scripts/k3s-node-setup.sh +2 -2
- package/scripts/nat-iptables.sh +103 -18
- package/scripts/rhel-grpc-setup.sh +56 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +58 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +23 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +148 -20
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/crypto/crypto.controller.js +8 -8
- package/src/api/crypto/crypto.service.js +8 -8
- package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
- package/src/api/cyberia-action/cyberia-action.model.js +87 -0
- package/src/api/cyberia-action/cyberia-action.router.js +27 -0
- package/src/api/cyberia-action/cyberia-action.service.js +42 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
- package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
- package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +178 -0
- package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
- package/src/api/cyberia-instance/cyberia-instance.model.js +87 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +156 -0
- package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
- package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +574 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +231 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
- package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
- package/src/api/cyberia-map/cyberia-map.model.js +30 -0
- package/src/api/cyberia-map/cyberia-map.router.js +40 -0
- package/src/api/cyberia-map/cyberia-map.service.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
- package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.ref.json +18 -0
- package/src/api/file/file.service.js +36 -36
- package/src/api/instance/instance.controller.js +10 -10
- package/src/api/instance/instance.model.js +4 -10
- package/src/api/instance/instance.service.js +10 -10
- package/src/api/ipfs/ipfs.controller.js +15 -36
- package/src/api/ipfs/ipfs.model.js +47 -47
- package/src/api/ipfs/ipfs.router.js +8 -13
- package/src/api/ipfs/ipfs.service.js +67 -129
- package/src/api/object-layer/object-layer.controller.js +12 -12
- package/src/api/object-layer/object-layer.model.js +4 -17
- package/src/api/object-layer/object-layer.router.js +30 -0
- package/src/api/object-layer/object-layer.service.js +126 -43
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +11 -27
- package/src/cli/cluster.js +68 -21
- package/src/cli/db.js +753 -825
- package/src/cli/deploy.js +215 -125
- package/src/cli/env.js +29 -0
- package/src/cli/fs.js +82 -8
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +74 -3
- package/src/cli/kubectl.js +211 -0
- package/src/cli/release.js +340 -0
- package/src/cli/repository.js +475 -74
- package/src/cli/run.js +582 -43
- package/src/cli/secrets.js +73 -0
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/cli/test.js +3 -3
- package/src/client/Cryptokoyn.index.js +18 -22
- package/src/client/CyberiaPortal.index.js +19 -24
- package/src/client/Default.index.js +21 -34
- package/src/client/Itemledger.index.js +20 -27
- package/src/client/Underpost.index.js +19 -24
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +69 -0
- package/src/client/components/core/Auth.js +35 -37
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +43 -64
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +64 -91
- package/src/client/components/core/DropDown.js +194 -96
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +96 -228
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +26 -19
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +43 -43
- package/src/client/components/core/LogOut.js +25 -16
- package/src/client/components/core/Modal.js +462 -179
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -51
- package/src/client/components/core/PanelForm.js +44 -144
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +48 -44
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +112 -30
- package/src/client/components/core/SocketIoHandler.js +75 -0
- package/src/client/components/core/Stream.js +143 -95
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Webhook.js +40 -7
- package/src/client/components/core/Worker.js +163 -27
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +59 -59
- package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +9 -7
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +8 -6
- package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
- package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
- package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
- package/src/client/components/cyberia/InstanceEngineCyberia.js +781 -0
- package/src/client/components/cyberia/MapEngineCyberia.js +1836 -2
- package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +1220 -99
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +252 -316
- package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +136 -103
- package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +462 -32
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +9 -7
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +8 -6
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -4
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +91 -91
- package/src/client/components/default/AppStoreDefault.js +5 -0
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +9 -7
- package/src/client/components/default/LogOutDefault.js +8 -6
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/SocketIoDefault.js +3 -51
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +59 -59
- package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
- package/src/client/components/itemledger/CssItemledger.js +15 -15
- package/src/client/components/itemledger/LogInItemledger.js +9 -7
- package/src/client/components/itemledger/LogOutItemledger.js +8 -6
- package/src/client/components/itemledger/RouterItemledger.js +38 -0
- package/src/client/components/itemledger/SettingsItemledger.js +4 -4
- package/src/client/components/itemledger/SignUpItemledger.js +6 -4
- package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
- package/src/client/components/itemledger/TranslateItemledger.js +3 -3
- package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +92 -92
- package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
- package/src/client/components/underpost/CssUnderpost.js +14 -14
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
- package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
- package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
- package/src/client/components/underpost/LogInUnderpost.js +9 -7
- package/src/client/components/underpost/LogOutUnderpost.js +8 -6
- package/src/client/components/underpost/RouterUnderpost.js +45 -0
- package/src/client/components/underpost/SettingsUnderpost.js +4 -4
- package/src/client/components/underpost/SignUpUnderpost.js +6 -4
- package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
- package/src/client/components/underpost/TranslateUnderpost.js +4 -4
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
- package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
- package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
- package/src/client/services/core/core.service.js +35 -55
- package/src/client/services/crypto/crypto.service.js +8 -13
- package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +116 -0
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
- package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
- package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
- package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
- package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
- package/src/client/services/default/default.management.js +159 -267
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/instance/instance.management.js +6 -6
- package/src/client/services/instance/instance.service.js +10 -15
- package/src/client/services/ipfs/ipfs.service.js +14 -40
- package/src/client/services/object-layer/object-layer.management.js +14 -14
- package/src/client/services/object-layer/object-layer.service.js +39 -24
- package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +86 -0
- package/src/client/services/user/user.management.js +6 -6
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
- package/src/client/ssr/head/PwaItemledger.js +197 -60
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/grpc/cyberia/grpc-server.js +642 -0
- package/src/index.js +24 -1
- package/src/runtime/cyberia-client/Dockerfile +80 -0
- package/src/runtime/cyberia-server/Dockerfile +37 -0
- package/src/runtime/express/Dockerfile +5 -1
- package/src/runtime/express/Express.js +18 -1
- package/src/runtime/lampp/Dockerfile +17 -5
- package/src/runtime/lampp/Lampp.js +27 -4
- package/src/runtime/wp/Dockerfile +62 -0
- package/src/runtime/wp/Wp.js +639 -0
- package/src/server/atlas-sprite-sheet-generator.js +4 -2
- package/src/server/auth.js +24 -1
- package/src/server/backup.js +37 -9
- package/src/server/client-build-docs.js +52 -46
- package/src/server/client-build.js +356 -82
- package/src/server/client-formatted.js +140 -57
- package/src/server/conf.js +29 -13
- package/src/server/cron.js +25 -23
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +24 -1
- package/src/server/ipfs-client.js +253 -89
- package/src/server/object-layer.js +150 -114
- package/src/server/peer.js +8 -0
- package/src/server/process.js +13 -27
- package/src/server/runtime.js +25 -1
- package/src/server/semantic-layer-generator-floor.js +319 -0
- package/src/server/semantic-layer-generator-resource.js +259 -0
- package/src/server/semantic-layer-generator-skin.js +1164 -0
- package/src/server/semantic-layer-generator.js +211 -542
- package/src/server/shape-generator.js +108 -0
- package/src/server/start.js +19 -5
- package/src/server/valkey.js +141 -235
- package/src/ws/IoInterface.js +1 -10
- package/src/ws/IoServer.js +14 -33
- package/src/ws/core/channels/core.ws.chat.js +65 -20
- package/src/ws/core/channels/core.ws.mailer.js +113 -32
- package/src/ws/core/channels/core.ws.stream.js +90 -31
- package/src/ws/core/core.ws.connection.js +12 -33
- package/src/ws/core/core.ws.emit.js +10 -26
- package/src/ws/core/core.ws.server.js +25 -58
- package/src/ws/default/channels/default.ws.main.js +53 -12
- package/src/ws/default/default.ws.connection.js +26 -13
- package/src/ws/default/default.ws.server.js +30 -12
- package/tsconfig.docs.json +15 -0
- package/typedoc.dd-cyberia.json +29 -0
- package/typedoc.json +29 -0
- package/WHITE-PAPER.md +0 -1540
- package/hardhat/README.md +0 -531
- package/hardhat/WHITE-PAPER.md +0 -1540
- package/jsdoc.dd-cyberia.json +0 -59
- package/jsdoc.json +0 -59
- package/src/api/object-layer/README.md +0 -347
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
- package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
- package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
- package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -58
- package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
- package/src/client/components/default/ElementsDefault.js +0 -38
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/components/itemledger/CommonItemledger.js +0 -29
- package/src/client/components/itemledger/ElementsItemledger.js +0 -38
- package/src/client/components/itemledger/RoutesItemledger.js +0 -40
- package/src/client/components/underpost/CommonUnderpost.js +0 -29
- package/src/client/components/underpost/ElementsUnderpost.js +0 -38
- package/src/client/components/underpost/RoutesUnderpost.js +0 -47
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
- package/src/ws/core/management/core.ws.chat.js +0 -8
- package/src/ws/core/management/core.ws.mailer.js +0 -16
- package/src/ws/core/management/core.ws.stream.js +0 -8
- package/src/ws/default/management/default.ws.main.js +0 -8
|
@@ -155,6 +155,26 @@ registerShape('parabola', (t, params) => {
|
|
|
155
155
|
return { x, y: a * x * x };
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
+
registerShape('thick-parabola', (t, params) => {
|
|
159
|
+
// Closed parabolic band — traces the outer curve forward then the inner
|
|
160
|
+
// curve backward, producing a thick filled crescent when rasterized.
|
|
161
|
+
// `a` controls curvature, `rangeX` controls horizontal span, and
|
|
162
|
+
// `thickness` controls band width (vertical gap between outer/inner).
|
|
163
|
+
const a = params.a ?? 0.6;
|
|
164
|
+
const rangeX = params.rangeX ?? 1.3;
|
|
165
|
+
const thickness = params.thickness ?? 0.35;
|
|
166
|
+
if (t <= 0.5) {
|
|
167
|
+
// Outer parabola (forward: left → right)
|
|
168
|
+
const u = t * 2;
|
|
169
|
+
const xNorm = -rangeX + 2 * rangeX * u;
|
|
170
|
+
return { x: xNorm, y: a * xNorm * xNorm };
|
|
171
|
+
}
|
|
172
|
+
// Inner parabola (reverse: right → left, shifted up by thickness)
|
|
173
|
+
const u = 1 - (t - 0.5) * 2;
|
|
174
|
+
const xNorm = -rangeX + 2 * rangeX * u;
|
|
175
|
+
return { x: xNorm, y: a * xNorm * xNorm + thickness };
|
|
176
|
+
});
|
|
177
|
+
|
|
158
178
|
registerShape('heart', (t) => {
|
|
159
179
|
const angle = t * Math.PI * 2;
|
|
160
180
|
const x = 16 * Math.pow(Math.sin(angle), 3);
|
|
@@ -408,6 +428,42 @@ registerShape('bezier-path', (t, params) => {
|
|
|
408
428
|
return { x, y };
|
|
409
429
|
});
|
|
410
430
|
|
|
431
|
+
registerShape('regular-polygon', (t, params) => {
|
|
432
|
+
// Regular convex polygon with `sides` edges.
|
|
433
|
+
// Traces straight vertex-to-vertex segments for perfect geometric figures.
|
|
434
|
+
const sides = Math.max(3, params.sides ?? 4);
|
|
435
|
+
const r = params.r ?? 1;
|
|
436
|
+
const segAngle = (2 * Math.PI) / sides;
|
|
437
|
+
const angle = t * Math.PI * 2;
|
|
438
|
+
// Which segment are we in?
|
|
439
|
+
const seg = Math.floor(angle / segAngle);
|
|
440
|
+
const frac = (angle - seg * segAngle) / segAngle;
|
|
441
|
+
// Offset: -π/2 puts first vertex at top (flat bottom for odd-sided).
|
|
442
|
+
// For even-sided polygons, shift by half a segment so edges are axis-aligned.
|
|
443
|
+
const offset = -Math.PI / 2 + (sides % 2 === 0 ? Math.PI / sides : 0);
|
|
444
|
+
const a0 = seg * segAngle + offset;
|
|
445
|
+
const a1 = (seg + 1) * segAngle + offset;
|
|
446
|
+
const x = r * ((1 - frac) * Math.cos(a0) + frac * Math.cos(a1));
|
|
447
|
+
const y = r * ((1 - frac) * Math.sin(a0) + frac * Math.sin(a1));
|
|
448
|
+
return { x, y };
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
registerShape('rectangle', (t, params) => {
|
|
452
|
+
// Axis-aligned rectangle with configurable aspect ratio.
|
|
453
|
+
// `width` and `height` control proportions (default: 1.4 × 1.0).
|
|
454
|
+
const w = params.width ?? 1.4;
|
|
455
|
+
const h = params.height ?? 1.0;
|
|
456
|
+
const hw = w / 2,
|
|
457
|
+
hh = h / 2;
|
|
458
|
+
const perim = 2 * (w + h);
|
|
459
|
+
const d = t * perim;
|
|
460
|
+
// Traverse: bottom-left → bottom-right → top-right → top-left
|
|
461
|
+
if (d < w) return { x: -hw + d, y: hh };
|
|
462
|
+
if (d < w + h) return { x: hw, y: hh - (d - w) };
|
|
463
|
+
if (d < 2 * w + h) return { x: hw - (d - w - h), y: -hh };
|
|
464
|
+
return { x: -hw, y: -hh + (d - 2 * w - h) };
|
|
465
|
+
});
|
|
466
|
+
|
|
411
467
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
412
468
|
* GEOMETRY HELPERS
|
|
413
469
|
* ═══════════════════════════════════════════════════════════════════════════ */
|
|
@@ -677,6 +733,49 @@ function rasterizeContour(normalizedPoints, gridW, gridH, closed) {
|
|
|
677
733
|
return unique;
|
|
678
734
|
}
|
|
679
735
|
|
|
736
|
+
/**
|
|
737
|
+
* Scanline-fills the interior of a closed contour on an integer grid.
|
|
738
|
+
* Takes the contour points produced by `rasterizeContour` and returns a
|
|
739
|
+
* new array containing both the contour AND all interior cells.
|
|
740
|
+
*
|
|
741
|
+
* Uses the standard even-odd scanline algorithm: for each row, find the
|
|
742
|
+
* leftmost and rightmost contour cell then fill everything in between.
|
|
743
|
+
*
|
|
744
|
+
* @param {ShapePoint[]} contourPoints - Contour cells from rasterizeContour.
|
|
745
|
+
* @param {number} gridW - Grid width.
|
|
746
|
+
* @param {number} gridH - Grid height.
|
|
747
|
+
* @returns {ShapePoint[]} All unique filled cells (contour + interior).
|
|
748
|
+
* @memberof ShapeGenerator
|
|
749
|
+
*/
|
|
750
|
+
function scanlineFill(contourPoints, gridW, gridH) {
|
|
751
|
+
// Build per-row min/max from contour
|
|
752
|
+
const rowBounds = new Map();
|
|
753
|
+
for (const p of contourPoints) {
|
|
754
|
+
const b = rowBounds.get(p.y);
|
|
755
|
+
if (b) {
|
|
756
|
+
if (p.x < b.min) b.min = p.x;
|
|
757
|
+
if (p.x > b.max) b.max = p.x;
|
|
758
|
+
} else {
|
|
759
|
+
rowBounds.set(p.y, { min: p.x, max: p.x });
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
const seen = new Set();
|
|
764
|
+
const filled = [];
|
|
765
|
+
|
|
766
|
+
for (const [y, { min, max }] of rowBounds) {
|
|
767
|
+
for (let x = min; x <= max; x++) {
|
|
768
|
+
const k = x * 100000 + y;
|
|
769
|
+
if (!seen.has(k)) {
|
|
770
|
+
seen.add(k);
|
|
771
|
+
filled.push({ x, y });
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
return filled;
|
|
777
|
+
}
|
|
778
|
+
|
|
680
779
|
/**
|
|
681
780
|
* Renders an integer-coordinate ShapeResult as an ASCII grid string.
|
|
682
781
|
* Useful for quick visual verification of pixel-art shapes.
|
|
@@ -738,6 +837,9 @@ export function renderGrid(shapeResult, opts = {}) {
|
|
|
738
837
|
* with Bresenham rasterization so that even on a 16×16 grid the full contour
|
|
739
838
|
* is visible as a connected set of cells. `count` is ignored in this mode;
|
|
740
839
|
* the number of output points equals the number of unique rasterized cells.
|
|
840
|
+
* @property {boolean} [fill=false] - When true (and intCoords is enabled),
|
|
841
|
+
* scanline-fills the interior of the closed contour, producing a solid
|
|
842
|
+
* silhouette instead of an outline-only shape.
|
|
741
843
|
* @memberof ShapeGenerator
|
|
742
844
|
*/
|
|
743
845
|
|
|
@@ -810,6 +912,7 @@ export function generateShape(key, options = {}) {
|
|
|
810
912
|
closed = true,
|
|
811
913
|
normalize = true,
|
|
812
914
|
intCoords = false,
|
|
915
|
+
fill = false,
|
|
813
916
|
color,
|
|
814
917
|
...extraParams
|
|
815
918
|
} = options;
|
|
@@ -896,6 +999,11 @@ export function generateShape(key, options = {}) {
|
|
|
896
999
|
if (useIntCoords) {
|
|
897
1000
|
points = rasterizeContour(points, gridW, gridH, closed);
|
|
898
1001
|
|
|
1002
|
+
// ---- Scanline fill (solid silhouette) -----------------------------------
|
|
1003
|
+
if (fill && closed) {
|
|
1004
|
+
points = scanlineFill(points, gridW, gridH);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
899
1007
|
// Build metadata for integer grid mode
|
|
900
1008
|
const bbox = computeBbox(points);
|
|
901
1009
|
/** @type {ShapeMetadata} */
|
package/src/server/start.js
CHANGED
|
@@ -131,11 +131,21 @@ class UnderpostStartUp {
|
|
|
131
131
|
* @param {boolean} options.build - Whether to build the deployment.
|
|
132
132
|
* @param {boolean} options.run - Whether to run the deployment.
|
|
133
133
|
* @param {boolean} options.underpostQuicklyInstall - Whether to use underpost quickly install.
|
|
134
|
+
* @param {boolean} options.skipPullBase - Whether to skip pulling the base code.
|
|
135
|
+
* @param {boolean} options.skipFullBuild - Whether to skip building the full client bundle.
|
|
136
|
+
* @param {boolean} options.pullBundle - When true, download pre-built client bundle from Cloudinary via pull-bundle before starting.
|
|
134
137
|
*/
|
|
135
138
|
async callback(
|
|
136
139
|
deployId = 'dd-default',
|
|
137
140
|
env = 'development',
|
|
138
|
-
options = {
|
|
141
|
+
options = {
|
|
142
|
+
build: false,
|
|
143
|
+
run: false,
|
|
144
|
+
underpostQuicklyInstall: false,
|
|
145
|
+
skipPullBase: false,
|
|
146
|
+
skipFullBuild: false,
|
|
147
|
+
pullBundle: false,
|
|
148
|
+
},
|
|
139
149
|
) {
|
|
140
150
|
Underpost.env.set('container-status', `${deployId}-${env}-build-deployment`);
|
|
141
151
|
if (options.build === true) await Underpost.start.build(deployId, env, options);
|
|
@@ -149,12 +159,15 @@ class UnderpostStartUp {
|
|
|
149
159
|
* @param {Object} options - Options for the build.
|
|
150
160
|
* @param {boolean} options.skipPullBase - Whether to skip pulling the base code and use the current workspace code directly.
|
|
151
161
|
* @param {boolean} options.underpostQuicklyInstall - Whether to use underpost quickly install.
|
|
162
|
+
* @param {boolean} options.skipFullBuild - Whether to skip building the full client bundle.
|
|
163
|
+
* @param {boolean} options.pullBundle - When true, download pre-built client bundle from Cloudinary via pull-bundle (must be pushed first with push-bundle).
|
|
164
|
+
* This flag is independent of skipFullBuild: it can be combined with skipFullBuild or used alone.
|
|
152
165
|
* @memberof UnderpostStartUp
|
|
153
166
|
*/
|
|
154
167
|
async build(
|
|
155
168
|
deployId = 'dd-default',
|
|
156
169
|
env = 'development',
|
|
157
|
-
options = { underpostQuicklyInstall: false, skipPullBase: false },
|
|
170
|
+
options = { underpostQuicklyInstall: false, skipPullBase: false, skipFullBuild: false, pullBundle: false },
|
|
158
171
|
) {
|
|
159
172
|
const buildBasePath = `/home/dd`;
|
|
160
173
|
const repoName = `engine-${deployId.split('-')[1]}`;
|
|
@@ -163,10 +176,9 @@ class UnderpostStartUp {
|
|
|
163
176
|
shellExec(`mkdir -p ${buildBasePath}/engine`);
|
|
164
177
|
shellExec(`cd ${buildBasePath} && sudo cp -a ./${repoName}/. ./engine`);
|
|
165
178
|
shellExec(`cd ${buildBasePath} && sudo rm -rf ./${repoName}`);
|
|
166
|
-
shellExec(`cd ${buildBasePath}/engine && underpost clone ${process.env.GITHUB_USERNAME}/${repoName}-private`);
|
|
167
|
-
shellExec(`cd ${buildBasePath}/engine && sudo mv ./${repoName}-private ./engine-private`);
|
|
168
179
|
}
|
|
169
180
|
shellCd(`${buildBasePath}/engine`);
|
|
181
|
+
Underpost.repo.privateEngineRepoFactory(deployId);
|
|
170
182
|
shellExec(options?.underpostQuicklyInstall ? `underpost install` : `npm install`);
|
|
171
183
|
shellExec(`node bin env ${deployId} ${env}`);
|
|
172
184
|
if (fs.existsSync('./engine-private/itc-scripts')) {
|
|
@@ -174,7 +186,8 @@ class UnderpostStartUp {
|
|
|
174
186
|
for (const itcScript of itcScripts)
|
|
175
187
|
if (itcScript.match(deployId)) shellExec(`node ./engine-private/itc-scripts/${itcScript}`);
|
|
176
188
|
}
|
|
177
|
-
shellExec(`node bin
|
|
189
|
+
if (options.pullBundle === true) shellExec(`node bin run pull-bundle --deploy-id ${deployId}`);
|
|
190
|
+
else if (!options.skipFullBuild) shellExec(`node bin client ${deployId}`);
|
|
178
191
|
},
|
|
179
192
|
/**
|
|
180
193
|
* Runs a deployment.
|
|
@@ -197,6 +210,7 @@ class UnderpostStartUp {
|
|
|
197
210
|
shellExec(`node bin env ${deployId} ${env}`);
|
|
198
211
|
shellExec(`npm ${runCmd} ${deployId}`, { async: true });
|
|
199
212
|
await awaitDeployMonitor(true);
|
|
213
|
+
if (env === 'production' && Underpost.env.isInsideContainer()) Underpost.secret.globalSecretClean();
|
|
200
214
|
Underpost.env.set('container-status', `${deployId}-${env}-running-deployment`);
|
|
201
215
|
},
|
|
202
216
|
};
|
package/src/server/valkey.js
CHANGED
|
@@ -1,293 +1,199 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Valkey connection and key-value store module.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Manage per-instance Valkey connections keyed by `${host}${path}`.
|
|
6
|
+
* - Provide a thin, typed CRUD surface: get / set / del / update.
|
|
7
|
+
* - Expose connection status helpers.
|
|
8
|
+
*
|
|
9
|
+
* Out of scope: domain model factories, DTO projection — those belong in
|
|
10
|
+
* their respective service modules (e.g. guest.service.js).
|
|
11
|
+
*
|
|
3
12
|
* @module src/server/valkey.js
|
|
4
13
|
* @namespace ValkeyService
|
|
5
14
|
*/
|
|
6
|
-
|
|
7
15
|
import Valkey from 'iovalkey';
|
|
8
|
-
import mongoose from 'mongoose';
|
|
9
|
-
import { hashPassword } from './auth.js';
|
|
10
16
|
import { loggerFactory } from './logger.js';
|
|
11
17
|
|
|
12
18
|
const logger = loggerFactory(import.meta);
|
|
13
19
|
|
|
14
|
-
//
|
|
20
|
+
// ─── Instance registry ────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
/** @type {Record<string, import('iovalkey').default>} */
|
|
15
23
|
const ValkeyInstances = {};
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
|
|
25
|
+
/** @type {Record<string, 'connected' | 'reconnecting' | 'error'>} */
|
|
26
|
+
const ValkeyStatus = {};
|
|
18
27
|
|
|
19
28
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* @returns {
|
|
23
|
-
* @memberof ValkeyService
|
|
29
|
+
* Derives the registry key from an instance descriptor.
|
|
30
|
+
* @param {{ host?: string, path?: string }} opts
|
|
31
|
+
* @returns {string}
|
|
24
32
|
*/
|
|
25
|
-
const
|
|
33
|
+
const _instanceKey = (opts = {}) => `${opts.host || ''}${opts.path || ''}`;
|
|
34
|
+
|
|
35
|
+
// ─── Connection ───────────────────────────────────────────────────────────────
|
|
26
36
|
|
|
27
37
|
/**
|
|
28
|
-
*
|
|
29
|
-
* @
|
|
30
|
-
* @param {string} [opts.host=''] - The host of the instance.
|
|
31
|
-
* @param {string} [opts.path=''] - The path of the instance.
|
|
32
|
-
* @returns {string} The instance key.
|
|
33
|
-
* @private
|
|
38
|
+
* Returns true when at least one Valkey instance is connected.
|
|
39
|
+
* @returns {boolean}
|
|
34
40
|
* @memberof ValkeyService
|
|
35
41
|
*/
|
|
36
|
-
const
|
|
42
|
+
const isValkeyEnable = () => Object.values(ValkeyStatus).some((s) => s === 'connected');
|
|
37
43
|
|
|
38
44
|
/**
|
|
39
|
-
* Creates
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* @param {string}
|
|
44
|
-
* @param {
|
|
45
|
-
* @returns {Promise<
|
|
45
|
+
* Creates a Valkey client for the given instance and waits for connectivity.
|
|
46
|
+
* Throws on connection failure — callers decide whether to abort or continue
|
|
47
|
+
* without Valkey.
|
|
48
|
+
*
|
|
49
|
+
* @param {{ host?: string, path?: string }} instance - Registry key descriptor.
|
|
50
|
+
* @param {{ host?: string, port?: number }} connectionOptions - iovalkey connection options.
|
|
51
|
+
* @returns {Promise<import('iovalkey').default>}
|
|
46
52
|
* @memberof ValkeyService
|
|
47
53
|
*/
|
|
48
|
-
const createValkeyConnection = async (
|
|
49
|
-
instance = { host: '', path: '' },
|
|
50
|
-
valkeyServerConnectionOptions = { host: '', path: '' },
|
|
51
|
-
) => {
|
|
54
|
+
const createValkeyConnection = async (instance = {}, connectionOptions = {}) => {
|
|
52
55
|
const key = _instanceKey(instance);
|
|
53
|
-
// Initialize dummy store for the instance
|
|
54
|
-
if (!DummyStores[key]) DummyStores[key] = new Map();
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
57
|
+
const client = new Valkey({
|
|
58
|
+
port: connectionOptions.port ?? undefined,
|
|
59
|
+
host: connectionOptions.host ?? undefined,
|
|
60
|
+
// Retry indefinitely with capped exponential backoff (1 s → 30 s)
|
|
61
|
+
retryStrategy: (attempt) => Math.min(attempt * 1000, 30000),
|
|
62
|
+
// Fail commands immediately when not connected; do NOT queue them
|
|
63
|
+
maxRetriesPerRequest: 0,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
client.on('ready', () => {
|
|
67
|
+
ValkeyStatus[key] = 'connected';
|
|
68
|
+
logger.info('Valkey connected', { instance });
|
|
69
|
+
});
|
|
70
|
+
client.on('error', (err) => {
|
|
71
|
+
ValkeyStatus[key] = 'error';
|
|
72
|
+
logger.error('Valkey error', { err: err?.message, instance });
|
|
73
|
+
});
|
|
74
|
+
client.on('reconnecting', () => {
|
|
75
|
+
ValkeyStatus[key] = 'reconnecting';
|
|
76
|
+
logger.warn('Valkey reconnecting...', { instance });
|
|
77
|
+
});
|
|
78
|
+
client.on('end', () => {
|
|
79
|
+
ValkeyStatus[key] = 'error';
|
|
80
|
+
logger.warn('Valkey connection ended', { instance });
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Verify connectivity with a probe before marking ready
|
|
84
|
+
await Promise.race([
|
|
85
|
+
(async () => {
|
|
80
86
|
try {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
await client.
|
|
84
|
-
await client.
|
|
87
|
+
const probe = `__vk_probe_${Date.now()}`;
|
|
88
|
+
await client.set(probe, '1');
|
|
89
|
+
await client.get(probe);
|
|
90
|
+
await client.del(probe);
|
|
85
91
|
ValkeyStatus[key] = 'connected';
|
|
86
|
-
} catch
|
|
87
|
-
ValkeyStatus[key] = '
|
|
88
|
-
logger.warn('Valkey probe failed, falling back to dummy', { instance, error: e?.message });
|
|
92
|
+
} catch {
|
|
93
|
+
ValkeyStatus[key] = 'error';
|
|
89
94
|
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
await Promise.race([probe(), new Promise((resolve) => setTimeout(resolve, 1000))]);
|
|
95
|
+
})(),
|
|
96
|
+
new Promise((resolve) => setTimeout(resolve, 1500)),
|
|
97
|
+
]);
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
ValkeyStatus[key] = 'dummy';
|
|
99
|
-
logger.warn('Valkey client creation failed, using dummy', { instance, error: err?.message });
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return ValkeyInstances[key];
|
|
99
|
+
ValkeyInstances[key] = client;
|
|
100
|
+
logger.info('Valkey instance registered', { key, status: ValkeyStatus[key] });
|
|
101
|
+
return client;
|
|
103
102
|
};
|
|
104
103
|
|
|
104
|
+
// ─── Internal client resolver ─────────────────────────────────────────────────
|
|
105
|
+
|
|
105
106
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* @
|
|
109
|
-
* @param {object} select - An object where keys are field names and values are 1 to include them.
|
|
110
|
-
* @returns {object} A new object containing only the selected fields from the payload.
|
|
111
|
-
* @memberof ValkeyService
|
|
107
|
+
* Resolves the connected client for an instance or throws.
|
|
108
|
+
* @param {{ host?: string, path?: string }} options
|
|
109
|
+
* @returns {import('iovalkey').default}
|
|
112
110
|
*/
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
const _client = (options) => {
|
|
112
|
+
const k = _instanceKey(options);
|
|
113
|
+
const client = ValkeyInstances[k];
|
|
114
|
+
if (!client || ValkeyStatus[k] !== 'connected') {
|
|
115
|
+
throw new Error(`Valkey instance not connected: ${k}`);
|
|
117
116
|
}
|
|
118
|
-
return
|
|
117
|
+
return client;
|
|
119
118
|
};
|
|
120
119
|
|
|
121
|
-
|
|
122
|
-
* Factory function to create a new Valkey client instance.
|
|
123
|
-
* @param {object} options - Connection options for the iovalkey client.
|
|
124
|
-
* @returns {Promise<Valkey>} A promise that resolves to a new Valkey client.
|
|
125
|
-
* @memberof ValkeyService
|
|
126
|
-
*/
|
|
127
|
-
const valkeyClientFactory = async (options) => {
|
|
128
|
-
const valkey = new Valkey({
|
|
129
|
-
port: options?.port ? options.port : undefined,
|
|
130
|
-
host: options?.host ? options.host : undefined,
|
|
131
|
-
// Keep retry strategy minimal; state handled in createValkeyConnection
|
|
132
|
-
retryStrategy: (attempt) => {
|
|
133
|
-
if (attempt === 1) return undefined; // stop aggressive retries early
|
|
134
|
-
return 1000; // retry interval if library continues
|
|
135
|
-
},
|
|
136
|
-
}); // Connect to 127.0.0.1:6379
|
|
137
|
-
// new Valkey(6380); // 127.0.0.1:6380
|
|
138
|
-
// new Valkey(6379, '192.168.1.1'); // 192.168.1.1:6379
|
|
139
|
-
// new Valkey('/tmp/redis.sock');
|
|
140
|
-
// new Valkey({
|
|
141
|
-
// port: 6379, // Valkey port
|
|
142
|
-
// host: '127.0.0.1', // Valkey host
|
|
143
|
-
// username: 'default', // needs Valkey >= 6
|
|
144
|
-
// password: 'my-top-secret',
|
|
145
|
-
// db: 0, // Defaults to 0
|
|
146
|
-
// });
|
|
147
|
-
return valkey;
|
|
148
|
-
};
|
|
120
|
+
// ─── CRUD ─────────────────────────────────────────────────────────────────────
|
|
149
121
|
|
|
150
122
|
/**
|
|
151
|
-
* Retrieves
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* @param {
|
|
155
|
-
* @param {string}
|
|
156
|
-
* @returns {Promise<object|string|null>}
|
|
123
|
+
* Retrieves and JSON-parses a value by key.
|
|
124
|
+
* Returns null when the key does not exist.
|
|
125
|
+
*
|
|
126
|
+
* @param {{ host?: string, path?: string }} options
|
|
127
|
+
* @param {string} key
|
|
128
|
+
* @returns {Promise<object | string | null>}
|
|
157
129
|
* @memberof ValkeyService
|
|
158
130
|
*/
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
|
|
131
|
+
const get = async (options, key) => {
|
|
132
|
+
const raw = await _client(options).get(key);
|
|
133
|
+
if (raw == null) return null;
|
|
162
134
|
try {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
return JSON.parse(value);
|
|
168
|
-
} catch {
|
|
169
|
-
// not JSON, return raw string
|
|
170
|
-
return value;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
} catch (err) {
|
|
174
|
-
logger.warn('Valkey get failed, using dummy', { key, err: err?.message });
|
|
135
|
+
return JSON.parse(raw);
|
|
136
|
+
} catch {
|
|
137
|
+
return raw;
|
|
175
138
|
}
|
|
176
|
-
// Dummy fallback returns stored value as-is (string or object)
|
|
177
|
-
return DummyStores[k]?.get(key) ?? null;
|
|
178
139
|
};
|
|
179
140
|
|
|
180
141
|
/**
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
* @param {
|
|
185
|
-
* @param {string}
|
|
186
|
-
* @param {object|string}
|
|
187
|
-
* @
|
|
142
|
+
* Serialises and stores a value by key.
|
|
143
|
+
* Pass `ttlMs` to set an expiry in milliseconds.
|
|
144
|
+
*
|
|
145
|
+
* @param {{ host?: string, path?: string }} options
|
|
146
|
+
* @param {string} key
|
|
147
|
+
* @param {object | string} payload
|
|
148
|
+
* @param {number} [ttlMs]
|
|
149
|
+
* @returns {Promise<string>} Resolves to 'OK'.
|
|
188
150
|
* @memberof ValkeyService
|
|
189
151
|
*/
|
|
190
|
-
const
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
if (ValkeyStatus[k] === 'connected' && ValkeyInstances[k]) {
|
|
196
|
-
return await ValkeyInstances[k].set(key, value);
|
|
197
|
-
}
|
|
198
|
-
} catch (err) {
|
|
199
|
-
logger.warn('Valkey set failed, writing to dummy', { key, err: err?.message });
|
|
200
|
-
}
|
|
201
|
-
if (!DummyStores[k]) DummyStores[k] = new Map();
|
|
202
|
-
// Store raw string or object accordingly
|
|
203
|
-
DummyStores[k].set(key, isString ? payload : payload);
|
|
204
|
-
return 'OK';
|
|
152
|
+
const set = async (options, key, payload, ttlMs) => {
|
|
153
|
+
const value = typeof payload === 'string' ? payload : JSON.stringify(payload);
|
|
154
|
+
if (ttlMs) return _client(options).set(key, value, 'PX', ttlMs);
|
|
155
|
+
return _client(options).set(key, value);
|
|
205
156
|
};
|
|
206
157
|
|
|
207
158
|
/**
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
* @param {
|
|
212
|
-
* @
|
|
213
|
-
* @param {object} [payload={}] - The new data to merge into the object.
|
|
214
|
-
* @returns {Promise<string>} A promise that resolves to the result of the set operation.
|
|
159
|
+
* Deletes a key.
|
|
160
|
+
*
|
|
161
|
+
* @param {{ host?: string, path?: string }} options
|
|
162
|
+
* @param {string} key
|
|
163
|
+
* @returns {Promise<number>}
|
|
215
164
|
* @memberof ValkeyService
|
|
216
165
|
*/
|
|
217
|
-
const
|
|
218
|
-
let base = await getValkeyObject(options, key);
|
|
219
|
-
if (typeof base !== 'object' || base === null) base = {};
|
|
220
|
-
base.updatedAt = new Date().toISOString();
|
|
221
|
-
return await setValkeyObject(options, key, { ...base, ...payload });
|
|
222
|
-
};
|
|
166
|
+
const del = async (options, key) => _client(options).del(key);
|
|
223
167
|
|
|
224
168
|
/**
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
* @param {
|
|
229
|
-
* @param {string}
|
|
230
|
-
* @param {object}
|
|
231
|
-
* @
|
|
232
|
-
* @returns {Promise<object>} A promise that resolves to the newly created object.
|
|
169
|
+
* Shallow-merges `payload` into the existing object stored at `key`
|
|
170
|
+
* and persists the result. The `updatedAt` timestamp is refreshed automatically.
|
|
171
|
+
*
|
|
172
|
+
* @param {{ host?: string, path?: string }} options
|
|
173
|
+
* @param {string} key
|
|
174
|
+
* @param {object} payload
|
|
175
|
+
* @returns {Promise<string>} Resolves to 'OK'.
|
|
233
176
|
* @memberof ValkeyService
|
|
234
177
|
*/
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
options
|
|
238
|
-
const { object } = options;
|
|
239
|
-
const _id = new mongoose.Types.ObjectId().toString();
|
|
240
|
-
object._id = _id;
|
|
241
|
-
object.createdAt = idoDate;
|
|
242
|
-
object.updatedAt = idoDate;
|
|
243
|
-
switch (model) {
|
|
244
|
-
case 'user': {
|
|
245
|
-
const role = 'guest';
|
|
246
|
-
object._id = `${role}${_id}`;
|
|
247
|
-
return {
|
|
248
|
-
...object,
|
|
249
|
-
username: `${role}${_id.slice(-5)}`,
|
|
250
|
-
email: `${_id}@${options.host}`,
|
|
251
|
-
password: hashPassword(process.env.JWT_SECRET),
|
|
252
|
-
role,
|
|
253
|
-
failedLoginAttempts: 0,
|
|
254
|
-
phoneNumbers: [],
|
|
255
|
-
publicKey: [],
|
|
256
|
-
profileImageId: null,
|
|
257
|
-
emailConfirmed: false,
|
|
258
|
-
recoverTimeOut: null,
|
|
259
|
-
lastLoginDate: null,
|
|
260
|
-
activeSessions: [],
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
default:
|
|
264
|
-
throw new Error(`model schema not found: ${model}`);
|
|
265
|
-
}
|
|
178
|
+
const update = async (options, key, payload) => {
|
|
179
|
+
const base = (await get(options, key)) ?? {};
|
|
180
|
+
return set(options, key, { ...base, ...payload, updatedAt: new Date().toISOString() });
|
|
266
181
|
};
|
|
267
182
|
|
|
183
|
+
// ─── Public API class ─────────────────────────────────────────────────────────
|
|
184
|
+
|
|
268
185
|
/**
|
|
269
|
-
*
|
|
270
|
-
* @
|
|
271
|
-
* @memberof ValkeyServiceService
|
|
186
|
+
* Namespace grouping all Valkey operations.
|
|
187
|
+
* @memberof ValkeyService
|
|
272
188
|
*/
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
createValkeyConnection
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
export {
|
|
284
|
-
valkeyClientFactory,
|
|
285
|
-
selectDtoFactory,
|
|
286
|
-
getValkeyObject,
|
|
287
|
-
setValkeyObject,
|
|
288
|
-
valkeyObjectFactory,
|
|
289
|
-
updateValkeyObject,
|
|
290
|
-
isValkeyEnable,
|
|
291
|
-
createValkeyConnection,
|
|
292
|
-
ValkeyAPI,
|
|
293
|
-
};
|
|
189
|
+
class ValkeyAPI {
|
|
190
|
+
/** @param {{ host?: string, path?: string }} options */
|
|
191
|
+
static isConnected = (options) => ValkeyStatus[_instanceKey(options)] === 'connected';
|
|
192
|
+
static get = get;
|
|
193
|
+
static set = set;
|
|
194
|
+
static del = del;
|
|
195
|
+
static update = update;
|
|
196
|
+
static createValkeyConnection = createValkeyConnection;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export { isValkeyEnable, createValkeyConnection, get, set, del, update, ValkeyAPI };
|