@futdevpro/nts-dynamo 1.15.71 → 1.15.73
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/.c8rc.json +26 -26
- package/.copilot/patterns.json +7 -7
- package/.cursor/rules/__assistant_guide.mdc +30 -30
- package/.cursor/rules/_ag_backend-structure.mdc +85 -85
- package/.cursor/rules/_ag_backend.mdc +16 -16
- package/.cursor/rules/_ag_frontend-structure.mdc +86 -86
- package/.cursor/rules/_ag_frontend.mdc +39 -39
- package/.cursor/rules/_ag_import-rules.mdc +44 -44
- package/.cursor/rules/_ag_naming.mdc +115 -115
- package/.cursor/rules/_ag_should-be.mdc +6 -6
- package/.cursor/rules/ai_development_guide.md +60 -60
- package/.cursor/rules/cursor-rules.md +160 -160
- package/.cursor/rules/default-command.mdc +464 -464
- package/.cursor/rules/error_code_pattern.md +39 -39
- package/.cursor/rules/saved rule mcp server use.md +15 -15
- package/.vscode/settings.json +10 -10
- package/HOWTO.md +15 -15
- package/LICENSE +21 -21
- package/__documentations/nts-integration-tests-2026-03-17.md +26 -26
- package/__documentations/plans/BEDROCK-HYPERPLAN.md +95 -0
- package/_specifications/BACKLOG.md +92 -92
- package/_specifications/TODO.md +15 -15
- package/_specifications/agent.md +138 -138
- package/build/_collections/global-settings.const.d.ts.map +1 -1
- package/build/_collections/global-settings.const.js +7 -0
- package/build/_collections/global-settings.const.js.map +1 -1
- package/build/_models/interfaces/global-settings.interface.d.ts +24 -0
- package/build/_models/interfaces/global-settings.interface.d.ts.map +1 -1
- package/build/_modules/local-vector-search/_services/lvs-vector-pool.control-service.d.ts +15 -0
- package/build/_modules/local-vector-search/_services/lvs-vector-pool.control-service.d.ts.map +1 -1
- package/build/_modules/local-vector-search/_services/lvs-vector-pool.control-service.js +34 -6
- package/build/_modules/local-vector-search/_services/lvs-vector-pool.control-service.js.map +1 -1
- package/build/_services/core/memory-guard.service.d.ts +51 -0
- package/build/_services/core/memory-guard.service.d.ts.map +1 -1
- package/build/_services/core/memory-guard.service.js +169 -6
- package/build/_services/core/memory-guard.service.js.map +1 -1
- package/eslint.config.js +3 -3
- package/nodemon.json +24 -24
- package/package.json +1 -1
- package/pnpm-workspace.yaml +5 -5
- package/scripts/run-coverage-tests.js +28 -28
- package/spec/support/helpers/spec-reporter-loader.js +359 -359
- package/spec/support/helpers/ts-node-helper.js +93 -93
- package/spec/support/jasmine.coverage.json +24 -24
- package/spec/support/jasmine.json +24 -24
- package/src/_collections/archive.util.spec.ts +57 -57
- package/src/_collections/archive.util.ts +18 -18
- package/src/_collections/atlas-default-db-options.const.ts +9 -9
- package/src/_collections/default-fallback-cache-max-age.const.spec.ts +11 -11
- package/src/_collections/default-fallback-cache-max-age.const.ts +2 -2
- package/src/_collections/default-not-found-page.const.spec.ts +19 -19
- package/src/_collections/default-not-found-page.const.ts +22 -22
- package/src/_collections/default-socket-path.const.spec.ts +12 -12
- package/src/_collections/default-socket-path.const.ts +2 -2
- package/src/_collections/get-environment-settings.util.spec.ts +210 -210
- package/src/_collections/get-environment-settings.util.ts +48 -48
- package/src/_collections/global-settings.const.ts +96 -89
- package/src/_collections/sample.env +21 -21
- package/src/_collections/star.controller.spec.ts +224 -224
- package/src/_collections/star.controller.ts +129 -129
- package/src/_enums/data-model-type.enum.ts +14 -14
- package/src/_enums/data-service-function.enum.ts +24 -24
- package/src/_enums/predefined-data-types.enum.ts +16 -16
- package/src/_enums/route-security.enum.ts +12 -12
- package/src/_models/control-models/api-call-params.control-model.spec.ts +152 -152
- package/src/_models/control-models/api-call-params.control-model.ts +142 -142
- package/src/_models/control-models/app-ext-system-controls.control-model.spec.ts +52 -52
- package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
- package/src/_models/control-models/app-params.control-model.spec.ts +225 -225
- package/src/_models/control-models/app-params.control-model.ts +136 -136
- package/src/_models/control-models/app-system-controls.control-model.spec.ts +31 -31
- package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
- package/src/_models/control-models/endpoint-params.control-model.spec.ts +627 -627
- package/src/_models/control-models/endpoint-params.control-model.ts +627 -627
- package/src/_models/control-models/http-settings.control-model.spec.ts +77 -77
- package/src/_models/control-models/http-settings.control-model.ts +37 -37
- package/src/_models/control-models/system-control.control-model.spec.ts +27 -27
- package/src/_models/control-models/system-control.control-model.ts +12 -12
- package/src/_models/interfaces/certification-settings.interface.ts +7 -7
- package/src/_models/interfaces/environment-settings.interface.ts +59 -59
- package/src/_models/interfaces/global-log-settings.interface.ts +171 -171
- package/src/_models/interfaces/global-service-settings.interface.ts +47 -47
- package/src/_models/interfaces/global-settings.interface.ts +24 -0
- package/src/_models/interfaces/routing-module-settings.interface.ts +21 -21
- package/src/_models/interfaces/static-client-settings.interface.spec.ts +29 -29
- package/src/_models/interfaces/static-client-settings.interface.ts +28 -28
- package/src/_models/types/db-update.type.ts +100 -100
- package/src/_modules/ai/_models/ai-input-interfaces.ts +117 -117
- package/src/_modules/ai/_models/ai-test-generation-result.interface.ts +16 -16
- package/src/_modules/ai/_modules/anthropic/_services/aai-user-key.control-service.ts +138 -138
- package/src/_modules/ai/_modules/anthropic/index.ts +5 -5
- package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.spec.ts +242 -242
- package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.ts +639 -639
- package/src/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.spec.ts +295 -295
- package/src/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.ts +518 -518
- package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.spec.ts +209 -209
- package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.ts +85 -85
- package/src/_modules/ai/_modules/document-ai/_enums/dai-compare-result-type.enum.ts +7 -7
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-chunk.data-model.ts +146 -146
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-page.data-model.ts +162 -162
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-document.data-model.ts +99 -99
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-code-chunk.interface.ts +68 -68
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-chunk-compare-result.interface.ts +18 -18
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-page-compare-result.interface.ts +19 -19
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-document-compare-result.interface.ts +25 -25
- package/src/_modules/ai/_modules/document-ai/index.ts +30 -30
- package/src/_modules/ai/_modules/fdp-ai/_services/fdpai-user-key.control-service.ts +189 -189
- package/src/_modules/ai/_modules/fdp-ai/index.ts +5 -5
- package/src/_modules/ai/_modules/open-ai/_collections/oai-global-settings.const.ts +9 -9
- package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests-hu.conts.ts +82 -82
- package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests.conts.ts +75 -75
- package/src/_modules/ai/_modules/open-ai/_enums/oai-gpt-message-role.enum.ts +45 -45
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-global-settings.interface.ts +7 -7
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-gpt-message.interface.ts +7 -7
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-llm-predefined-requests.interface.ts +57 -57
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-chunk-data.service.ts +292 -292
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-document.data-service.spec.ts +342 -342
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.spec.ts +550 -550
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.ts +630 -630
- package/src/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.spec.ts +332 -332
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.spec.ts +462 -462
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.ts +634 -634
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.spec.ts +489 -489
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.tools.spec.ts +173 -173
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.ts +1033 -1033
- package/src/_modules/ai/_modules/open-ai/_services/oai-user-key.control-service.ts +157 -157
- package/src/_modules/ai/_services/ai-embedding-mock.service.spec.ts +115 -115
- package/src/_modules/ai/_services/ai-embedding-mock.service.ts +212 -212
- package/src/_modules/ai/_services/ai-embedding-provider.registry.spec.ts +110 -110
- package/src/_modules/ai/_services/ai-embedding-provider.registry.ts +110 -110
- package/src/_modules/ai/_services/ai-embedding.service-base.spec.ts +98 -98
- package/src/_modules/ai/_services/ai-embedding.service-base.ts +48 -48
- package/src/_modules/ai/_services/ai-llm-chat.service-base.spec.ts +229 -229
- package/src/_modules/ai/_services/ai-llm-chat.service-base.ts +68 -68
- package/src/_modules/ai/_services/ai-llm.service-base.spec.ts +250 -250
- package/src/_modules/ai/_services/ai-llm.service-base.ts +519 -519
- package/src/_modules/ai/_services/ai-provider.service-base.spec.ts +158 -158
- package/src/_modules/ai/_services/ai-user-key.service-base.ts +59 -59
- package/src/_modules/ai/_services/lmstudio-embedding.control-service.spec.ts +197 -197
- package/src/_modules/ai/_services/lmstudio-embedding.control-service.ts +371 -371
- package/src/_modules/ai/index.ts +23 -23
- package/src/_modules/assistant/_collections/ass-global-settings.const.ts +13 -13
- package/src/_modules/assistant/_collections/ass.util.spec.ts +176 -176
- package/src/_modules/assistant/_collections/ass.util.ts +50 -50
- package/src/_modules/assistant/_models/ass-global-settings.interface.ts +15 -15
- package/src/_modules/assistant/_services/ass-io.control-service.spec.ts +140 -140
- package/src/_modules/assistant/_services/ass-main.control-service.spec.ts +192 -192
- package/src/_modules/assistant/_services/ass-main.control-service.ts +107 -107
- package/src/_modules/bot/_collections/bot-default-commands.const.ts +12 -12
- package/src/_modules/bot/_collections/bot-global-settings.const.ts +39 -39
- package/src/_modules/bot/_models/bot-channel-wrapper.interface.ts +62 -62
- package/src/_modules/bot/_models/bot-command.interface.ts +8 -8
- package/src/_modules/bot/_models/bot-global-settings.interface.ts +96 -96
- package/src/_modules/bot/_models/bot-last-mention-date.interface.ts +6 -6
- package/src/_modules/bot/_models/bot-last-message-date.interface.ts +5 -5
- package/src/_modules/bot/_models/bot-user-wrapper.interface.ts +41 -41
- package/src/_modules/bot/_modules/discord-bot/_models/dib-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.spec.ts +431 -431
- package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.spec.ts +160 -160
- package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.ts +55 -55
- package/src/_modules/bot/_modules/dynamo-bot/_models/dyb-platform.types.ts +15 -15
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.spec.ts +374 -374
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts +447 -447
- package/src/_modules/bot/_modules/dynamo-bot/index.ts +15 -15
- package/src/_modules/bot/_modules/slack-bot/_models/slb-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.spec.ts +344 -344
- package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.ts +197 -197
- package/src/_modules/bot/_modules/teams-bot/_models/teb-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.spec.ts +345 -345
- package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.ts +197 -197
- package/src/_modules/bot/_services/bot-commands.control-service.spec.ts +116 -116
- package/src/_modules/bot/_services/bot-io.control-service.spec.ts +285 -285
- package/src/_modules/bot/_services/bot-main.control-service.spec.ts +208 -208
- package/src/_modules/bot/_services/bot-messaging-provider.service-base.spec.ts +349 -349
- package/src/_modules/bot/_services/bot-routines.control-service.spec.ts +111 -111
- package/src/_modules/custom-data/custom-data.controller.spec.ts +49 -49
- package/src/_modules/custom-data/custom-data.controller.ts +67 -67
- package/src/_modules/custom-data/custom-data.data-service.spec.ts +54 -54
- package/src/_modules/custom-data/custom-data.data-service.ts +21 -21
- package/src/_modules/custom-data/get-custom-data-routing-module.util.spec.ts +28 -28
- package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +24 -24
- package/src/_modules/custom-data/index.ts +9 -9
- package/src/_modules/data-readers/_collections/dynts-sqlite-reader.util.spec.ts +161 -161
- package/src/_modules/data-readers/_collections/dynts-sqlite-reader.util.ts +203 -203
- package/src/_modules/data-readers/_models/interfaces/dynts-sqlite-reader.interface.ts +33 -33
- package/src/_modules/data-readers/index.ts +11 -11
- package/src/_modules/defaults/_collections/default-endpoints.util.ts +487 -487
- package/src/_modules/defaults/_models/default-user.data-model.ts +72 -72
- package/src/_modules/defaults/_services/default-auth.service.spec.ts +269 -269
- package/src/_modules/defaults/_services/default-auth.service.ts +177 -177
- package/src/_modules/defaults/_services/default-socket-events.service.spec.ts +42 -42
- package/src/_modules/defaults/_services/default-socket-events.service.ts +61 -61
- package/src/_modules/defaults/_services/default-user.data-service.spec.ts +187 -187
- package/src/_modules/defaults/_services/default-user.data-service.ts +98 -98
- package/src/_modules/defaults/index.ts +17 -17
- package/src/_modules/discord-assistant/_collections/dias-global-settings.const.ts +19 -19
- package/src/_modules/discord-assistant/_collections/dias.util.spec.ts +366 -366
- package/src/_modules/discord-assistant/_collections/dias.util.ts +132 -132
- package/src/_modules/discord-assistant/_models/dias-global-settings.interface.ts +19 -19
- package/src/_modules/discord-assistant/_models/dias-knowledge.data-model.ts +52 -52
- package/src/_modules/discord-assistant/_services/dias-chunk.data-service.ts +177 -177
- package/src/_modules/discord-assistant/_services/dias-io.control-service.spec.ts +108 -108
- package/src/_modules/discord-assistant/_services/dias-io.control-service.ts +69 -69
- package/src/_modules/discord-assistant/_services/dias-main.control-service.spec.ts +22 -22
- package/src/_modules/discord-assistant/_services/dias-main.control-service.ts +27 -27
- package/src/_modules/discord-assistant/_services/dias.service-base.spec.ts +195 -195
- package/src/_modules/discord-assistant/_services/dias.service-base.ts +76 -76
- package/src/_modules/discord-assistant/index.ts +38 -38
- package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.spec.ts +34 -34
- package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.ts +11 -11
- package/src/_modules/discord-assistant-voiced/index.ts +36 -36
- package/src/_modules/discord-bot/_collections/dibo-default-commands.const.ts +16 -16
- package/src/_modules/discord-bot/_collections/dibo-global-settings.conts.ts +55 -55
- package/src/_modules/discord-bot/_collections/dibo-operations.util.spec.ts +214 -214
- package/src/_modules/discord-bot/_collections/dibo-operations.util.ts +387 -387
- package/src/_modules/discord-bot/_models/dibo-command.interface.ts +12 -12
- package/src/_modules/discord-bot/_models/dibo-global-settings.interface.ts +98 -98
- package/src/_modules/discord-bot/_models/dibo-last-mention-date.inteface.ts +7 -7
- package/src/_modules/discord-bot/_models/dibo-last-message-date.interface.ts +6 -6
- package/src/_modules/discord-bot/_services/dibo-commands.control-service.spec.ts +154 -154
- package/src/_modules/discord-bot/_services/dibo-commands.control-service.ts +153 -153
- package/src/_modules/discord-bot/_services/dibo-io.control-service.spec.ts +264 -264
- package/src/_modules/discord-bot/_services/dibo-io.control-service.ts +306 -306
- package/src/_modules/discord-bot/_services/dibo-main.control-service.spec.ts +408 -408
- package/src/_modules/discord-bot/_services/dibo-main.control-service.ts +487 -487
- package/src/_modules/discord-bot/_services/dibo-routines.control-service.spec.ts +105 -105
- package/src/_modules/discord-bot/index.ts +36 -36
- package/src/_modules/local-vector-search/_enums/lvs-search-mode.enum.ts +35 -35
- package/src/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.ts +59 -59
- package/src/_modules/local-vector-search/_models/lvs-search-result.interface.ts +17 -17
- package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.spec.ts +418 -418
- package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.ts +276 -276
- package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.spec.ts +480 -480
- package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.ts +416 -416
- package/src/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.spec.ts +198 -198
- package/src/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.ts +146 -146
- package/src/_modules/local-vector-search/_services/lvs-vector-persist.data-service.spec.ts +167 -167
- package/src/_modules/local-vector-search/_services/lvs-vector-persist.data-service.ts +106 -106
- package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.spec.ts +507 -455
- package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.ts +272 -239
- package/src/_modules/local-vector-search/index.ts +16 -16
- package/src/_modules/logs/index.ts +11 -11
- package/src/_modules/mcp/_models/interfaces/dynts-mcp.interface.ts +111 -111
- package/src/_modules/mcp/_services/dynts-mcp-server.service-base.spec.ts +142 -142
- package/src/_modules/mcp/_services/dynts-mcp-server.service-base.ts +120 -120
- package/src/_modules/mcp/_services/dynts-mcp.adapter.ts +168 -168
- package/src/_modules/mcp/index.ts +13 -13
- package/src/_modules/messaging/README.md +354 -354
- package/src/_modules/messaging/_collections/get-messaging-routing-module.util.ts +26 -26
- package/src/_modules/messaging/_collections/msg-global-settings.const.ts +22 -22
- package/src/_modules/messaging/_collections/msg.util.spec.ts +226 -226
- package/src/_modules/messaging/_models/msg-global-settings.interface.ts +37 -37
- package/src/_modules/messaging/_services/msg-conversation.data-service.ts +146 -146
- package/src/_modules/messaging/_services/msg-events.service.spec.ts +219 -219
- package/src/_modules/messaging/_services/msg-events.service.ts +267 -267
- package/src/_modules/messaging/_services/msg-integration.control-service.ts +179 -179
- package/src/_modules/messaging/_services/msg-main.control-service.spec.ts +147 -147
- package/src/_modules/messaging/_services/msg-main.control-service.ts +571 -571
- package/src/_modules/messaging/_services/msg-message.data-service.ts +129 -129
- package/src/_modules/messaging/_services/msg.controller.spec.ts +201 -201
- package/src/_modules/messaging/index.ts +30 -30
- package/src/_modules/mock/app-extended-server.mock.ts +201 -201
- package/src/_modules/mock/app-integration-test.mock.ts +51 -51
- package/src/_modules/mock/app-params.mock.spec.ts +21 -21
- package/src/_modules/mock/app-params.mock.ts +9 -9
- package/src/_modules/mock/app-server.mock.ts +188 -188
- package/src/_modules/mock/auth-service.mock.spec.ts +47 -47
- package/src/_modules/mock/auth-service.mock.ts +28 -28
- package/src/_modules/mock/controller.mock.spec.ts +26 -26
- package/src/_modules/mock/controller.mock.ts +16 -16
- package/src/_modules/mock/data-model.mock.spec.ts +111 -111
- package/src/_modules/mock/data-model.mock.ts +82 -82
- package/src/_modules/mock/email-service-collection.mock.spec.ts +24 -24
- package/src/_modules/mock/email-service-collection.mock.ts +15 -15
- package/src/_modules/mock/email-service.mock.spec.ts +17 -17
- package/src/_modules/mock/email-service.mock.ts +20 -20
- package/src/_modules/mock/email-template.mock.html +14 -14
- package/src/_modules/mock/endpoint.mock.ts +91 -91
- package/src/_modules/mock/socket-client.mock.spec.ts +40 -40
- package/src/_modules/mock/socket-client.mock.ts +45 -45
- package/src/_modules/mock/socket-server.mock.spec.ts +44 -44
- package/src/_modules/mock/socket-server.mock.ts +46 -46
- package/src/_modules/oauth2/_routes/oauth2.controller.spec.ts +107 -107
- package/src/_modules/oauth2/_routes/oauth2.controller.ts +98 -98
- package/src/_modules/oauth2/_services/oauth2.auth-service.spec.ts +254 -254
- package/src/_modules/oauth2/_services/oauth2.auth-service.ts +232 -232
- package/src/_modules/oauth2/_services/oauth2.control-service.spec.ts +585 -585
- package/src/_modules/oauth2/_services/oauth2.control-service.ts +653 -653
- package/src/_modules/oauth2/index.ts +17 -17
- package/src/_modules/scoped-config/_enums/dynts-scoped-config-level.enum.ts +22 -22
- package/src/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.ts +81 -81
- package/src/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.ts +107 -107
- package/src/_modules/scoped-config/_services/dynts-scoped-config.control-service.spec.ts +306 -306
- package/src/_modules/scoped-config/_services/dynts-scoped-config.control-service.ts +295 -295
- package/src/_modules/scoped-config/_services/dynts-scoped-config.data-service.spec.ts +118 -118
- package/src/_modules/scoped-config/_services/dynts-scoped-config.data-service.ts +105 -105
- package/src/_modules/scoped-config/index.ts +17 -17
- package/src/_modules/server/errors/errors.control-service.spec.ts +238 -238
- package/src/_modules/server/errors/errors.control-service.ts +100 -100
- package/src/_modules/server/errors/errors.controller.spec.ts +241 -241
- package/src/_modules/server/errors/errors.controller.ts +489 -489
- package/src/_modules/server/errors/errors.data-service.spec.ts +480 -480
- package/src/_modules/server/index.ts +30 -30
- package/src/_modules/server/server-status/server-status-snapshot.control-service.spec.ts +70 -70
- package/src/_modules/server/server-status/server-status-snapshot.control-service.ts +17 -17
- package/src/_modules/server/server-status/server-status-snapshot.data-service.spec.ts +77 -77
- package/src/_modules/server/server-status/server-status-snapshot.data-service.ts +37 -37
- package/src/_modules/server/server-status/server-status.control-service.spec.ts +576 -576
- package/src/_modules/server/server-status/server-status.control-service.ts +396 -396
- package/src/_modules/server/server-status/server-status.controller.spec.ts +240 -240
- package/src/_modules/server/server-status/server-status.controller.ts +253 -253
- package/src/_modules/socket/_enums/socket-security.enum.ts +11 -11
- package/src/_modules/socket/_models/socket-client-service-params.control-model.spec.ts +32 -32
- package/src/_modules/socket/_models/socket-client-service-params.control-model.ts +22 -22
- package/src/_modules/socket/_models/socket-presence.control-model.spec.ts +164 -164
- package/src/_modules/socket/_models/socket-presence.control-model.ts +210 -210
- package/src/_modules/socket/_models/socket-server-service-params.control-model.spec.ts +46 -46
- package/src/_modules/socket/_models/socket-server-service-params.control-model.ts +22 -22
- package/src/_modules/socket/_services/socket-client.service.spec.ts +15 -15
- package/src/_modules/socket/_services/socket-client.service.ts +260 -260
- package/src/_modules/socket/_services/socket-server.service.spec.ts +11 -11
- package/src/_modules/socket/app-extended.integration.spec.ts +85 -85
- package/src/_modules/socket/app-extended.server.ts +630 -630
- package/src/_modules/socket/index.ts +42 -42
- package/src/_modules/test/get-test-routing-module.util.spec.ts +28 -28
- package/src/_modules/test/get-test-routing-module.util.ts +23 -23
- package/src/_modules/test/index.ts +11 -11
- package/src/_modules/test/test.controller.spec.ts +72 -72
- package/src/_modules/test/test.controller.ts +115 -115
- package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
- package/src/_modules/usage/index.ts +15 -15
- package/src/_modules/usage/usage.controller.spec.ts +81 -81
- package/src/_modules/usage/usage.controller.ts +126 -126
- package/src/_modules/usage/usage.data-service.spec.ts +332 -332
- package/src/_modules/usage/usage.data-service.ts +185 -185
- package/src/_services/base/api.service-base.spec.ts +125 -125
- package/src/_services/base/api.service-base.ts +74 -74
- package/src/_services/base/archive-data.service.spec.ts +196 -196
- package/src/_services/base/archive-data.service.ts +216 -216
- package/src/_services/base/data.service.spec.ts +674 -674
- package/src/_services/base/data.service.ts +2719 -2719
- package/src/_services/base/db.service.spec.ts +73 -73
- package/src/_services/base/db.service.ts +1575 -1575
- package/src/_services/base/singleton.service-base.spec.ts +28 -28
- package/src/_services/base/singleton.service-base.ts +24 -24
- package/src/_services/base/singleton.service.spec.ts +114 -114
- package/src/_services/base/singleton.service.ts +38 -38
- package/src/_services/core/api.service.spec.ts +140 -140
- package/src/_services/core/auth.service.spec.ts +159 -159
- package/src/_services/core/auth.service.ts +174 -174
- package/src/_services/core/email.service.spec.ts +85 -85
- package/src/_services/core/email.service.ts +742 -742
- package/src/_services/core/global.service.spec.ts +292 -292
- package/src/_services/core/global.service.ts +475 -475
- package/src/_services/core/memory-guard.service.spec.ts +62 -0
- package/src/_services/core/memory-guard.service.ts +195 -6
- package/src/_services/core/service-collection.service.spec.ts +46 -46
- package/src/_services/core/service-collection.service.ts +6 -6
- package/src/_services/route/controller.service.spec.ts +53 -53
- package/src/_services/route/controller.service.ts +148 -148
- package/src/_services/route/routing-module.service.spec.ts +98 -98
- package/src/_services/route/routing-module.service.ts +330 -330
- package/src/_services/server/app.server.ts +1747 -1747
- package/src/_services/shared.static-service.spec.ts +99 -99
- package/src/_services/shared.static-service.ts +78 -78
- package/src/index.ts +96 -96
- package/tsconfig.app.json +12 -12
- package/tsconfig.json +42 -42
- package/.dynamo/logs/cicd-pipeline/output.log +0 -2782
- package/.dynamo/logs/cicd-pipeline/status.json +0 -94
|
@@ -49,6 +49,11 @@ describe('| DyNTS_MemoryGuard (FR-193)', (): void => {
|
|
|
49
49
|
heapCriticalThreshold: 95,
|
|
50
50
|
recoveryMargin: 10,
|
|
51
51
|
maxHistoryCount: 100,
|
|
52
|
+
gcWarningFraction: 0.40,
|
|
53
|
+
gcCriticalFraction: 0.60,
|
|
54
|
+
// A tesztek NE regisztráljanak process-szintű crash-handlert / ne lépjenek ki (a jasmine-harness védelme).
|
|
55
|
+
installCrashHandlers: false,
|
|
56
|
+
exitOnSustainedCritical: false,
|
|
52
57
|
};
|
|
53
58
|
|
|
54
59
|
originalSink = DyNTS_GlobalService.globalErrorHandler;
|
|
@@ -162,4 +167,61 @@ describe('| DyNTS_MemoryGuard (FR-193)', (): void => {
|
|
|
162
167
|
expect(guard.getStatus().peakHeapPct).toBe(92);
|
|
163
168
|
expect(guard.getStatus().peakRssMb).toBeGreaterThan(0);
|
|
164
169
|
});
|
|
170
|
+
|
|
171
|
+
// --- GC-thrash precursor (a %-küszöb ALATT is OOM-jel) ---
|
|
172
|
+
|
|
173
|
+
it('| GC-thrash kritikus, bár a heap-% csak 70% (a %-küszöb ALATT) — trigger=gc', (): void => {
|
|
174
|
+
guard.install();
|
|
175
|
+
mockHeap(guard, 1000, 700); // 70% < warn 85
|
|
176
|
+
spyOn(guard as any, 'recentGcFraction').and.returnValue(0.65); // GC 65% ≥ crit 60%
|
|
177
|
+
poll(guard);
|
|
178
|
+
const hist: ReturnType<typeof guard.getHistory> = guard.getHistory();
|
|
179
|
+
expect(hist[hist.length - 1].level).toBe('critical');
|
|
180
|
+
expect(hist[hist.length - 1].trigger).toBe('gc');
|
|
181
|
+
expect(sinkSpy).toHaveBeenCalledTimes(1);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('| közepes GC (40–60%) alacsony heap-nél → warning (trigger=gc)', (): void => {
|
|
185
|
+
guard.install();
|
|
186
|
+
mockHeap(guard, 1000, 700); // 70%
|
|
187
|
+
spyOn(guard as any, 'recentGcFraction').and.returnValue(0.45);
|
|
188
|
+
poll(guard);
|
|
189
|
+
expect(guard.getHistory()[0].level).toBe('warning');
|
|
190
|
+
expect(guard.getHistory()[0].trigger).toBe('gc');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// --- pressure() / shouldShedLoad() — a fogyasztói load-shed gate ---
|
|
194
|
+
|
|
195
|
+
it('| pressure() a heap-% + GC közül a rosszabb szintet adja; shouldShedLoad critical-nál true', (): void => {
|
|
196
|
+
guard.install();
|
|
197
|
+
mockHeap(guard, 1000, 970); // 97% ≥ crit
|
|
198
|
+
spyOn(guard as any, 'recentGcFraction').and.returnValue(0.0);
|
|
199
|
+
const p = guard.pressure();
|
|
200
|
+
expect(p.level).toBe('critical');
|
|
201
|
+
expect(p.heapPct).toBe(97);
|
|
202
|
+
expect(guard.shouldShedLoad()).toBe(true);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('| shouldShedLoad false, ha ok-szint (alacsony heap + alacsony GC)', (): void => {
|
|
206
|
+
guard.install();
|
|
207
|
+
mockHeap(guard, 1000, 500); // 50%
|
|
208
|
+
spyOn(guard as any, 'recentGcFraction').and.returnValue(0.10);
|
|
209
|
+
expect(guard.pressure().level).toBe('ok');
|
|
210
|
+
expect(guard.shouldShedLoad()).toBe(false);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// --- graceful-exit: tartós critical → exit (a wrapper újraindít) ---
|
|
214
|
+
|
|
215
|
+
it('| exitOnSustainedCritical: N egymás utáni critical poll → gracefulExit (process.exit)', (): void => {
|
|
216
|
+
DyNTS_global_settings.memoryGuard!.exitOnSustainedCritical = true;
|
|
217
|
+
DyNTS_global_settings.memoryGuard!.sustainedCriticalPolls = 3;
|
|
218
|
+
const exitSpy: jasmine.Spy = spyOn(guard as any, 'gracefulExit').and.stub();
|
|
219
|
+
guard.install();
|
|
220
|
+
mockHeap(guard, 1000, 970); // 97% critical
|
|
221
|
+
spyOn(guard as any, 'recentGcFraction').and.returnValue(0.0);
|
|
222
|
+
poll(guard); poll(guard);
|
|
223
|
+
expect(exitSpy).not.toHaveBeenCalled(); // 2 critical < 3
|
|
224
|
+
poll(guard);
|
|
225
|
+
expect(exitSpy).toHaveBeenCalledTimes(1); // a 3. critical → exit
|
|
226
|
+
});
|
|
165
227
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as v8 from 'v8';
|
|
2
|
+
import { PerformanceObserver } from 'perf_hooks';
|
|
2
3
|
|
|
3
4
|
import { DyFM_Error, DyFM_ErrorLevel, DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
4
5
|
|
|
@@ -47,6 +48,10 @@ export interface DyNTS_MemoryGuard_Event {
|
|
|
47
48
|
rssMb: number;
|
|
48
49
|
/** External (C++ / Buffer) memória MB-ban. */
|
|
49
50
|
externalMb: number;
|
|
51
|
+
/** A közelmúlt GC-hányada (GC-ben töltött idő / poll-ablak; 0..1) — a mark-compact-thrash / OOM-precursor jelzője. */
|
|
52
|
+
gcFraction: number;
|
|
53
|
+
/** Mi váltotta ki az esemény-szintet: a heap-% küszöb, a GC-thrash, vagy mindkettő. */
|
|
54
|
+
trigger: 'heap' | 'gc' | 'heap+gc' | 'recovery';
|
|
50
55
|
/** Esemény időbélyege (ISO). */
|
|
51
56
|
at: string;
|
|
52
57
|
}
|
|
@@ -63,6 +68,18 @@ export interface DyNTS_MemoryGuard_Config {
|
|
|
63
68
|
recoveryMargin?: number;
|
|
64
69
|
/** Megőrzött események max száma (ring-buffer). Default: 100. */
|
|
65
70
|
maxHistoryCount?: number;
|
|
71
|
+
/** GC-hányad-küszöb a `warning`-hoz (0..1). Default: 0.40. */
|
|
72
|
+
gcWarningFraction?: number;
|
|
73
|
+
/** GC-hányad-küszöb a `critical`-hoz (0..1). Default: 0.60. */
|
|
74
|
+
gcCriticalFraction?: number;
|
|
75
|
+
/** `uncaughtException` crash-handler telepítése (teljes-részletű error-entry + tiszta exit). Default: true. */
|
|
76
|
+
installCrashHandlers?: boolean;
|
|
77
|
+
/** Tartós critical → tiszta exit (a wrapper újraindít). Default: false. */
|
|
78
|
+
exitOnSustainedCritical?: boolean;
|
|
79
|
+
/** Hány egymást követő critical poll után lép ki. Default: 3. */
|
|
80
|
+
sustainedCriticalPolls?: number;
|
|
81
|
+
/** A graceful-exit kódja. Default: 137. */
|
|
82
|
+
exitCode?: number;
|
|
66
83
|
/** Hook, amit a `critical` küszöb átlépésekor hívunk (pl. terhelés-dobás). */
|
|
67
84
|
onCritical?: (event: DyNTS_MemoryGuard_Event) => void;
|
|
68
85
|
}
|
|
@@ -87,12 +104,24 @@ export class DyNTS_MemoryGuard extends DyNTS_SingletonServiceBase {
|
|
|
87
104
|
private critPct: number = 95;
|
|
88
105
|
private recoveryMargin: number = 10;
|
|
89
106
|
private maxHistoryCount: number = 100;
|
|
107
|
+
private gcWarnFraction: number = 0.40;
|
|
108
|
+
private gcCritFraction: number = 0.60;
|
|
109
|
+
private exitOnSustainedCritical: boolean = false;
|
|
110
|
+
private sustainedCriticalPolls: number = 3;
|
|
111
|
+
private exitCode: number = 137;
|
|
90
112
|
private onCritical?: (event: DyNTS_MemoryGuard_Event) => void;
|
|
91
113
|
|
|
92
114
|
private readonly history: DyNTS_MemoryGuard_Event[] = [];
|
|
93
115
|
private peakHeapPct: number = 0;
|
|
94
116
|
private peakRssMb: number = 0;
|
|
95
117
|
|
|
118
|
+
// GC-thrash követés (perf_hooks 'gc') — a GC-ben töltött ms gördülő ablaka + a critical-streak számláló.
|
|
119
|
+
private gcObserver: PerformanceObserver | null = null;
|
|
120
|
+
private gcEvents: { at: number; ms: number }[] = [];
|
|
121
|
+
private criticalStreak: number = 0;
|
|
122
|
+
// A telepített crash-handler ref-ek (a teardown eltávolításához).
|
|
123
|
+
private crashHandler: ((error: Error) => void) | null = null;
|
|
124
|
+
|
|
96
125
|
protected constructor() {
|
|
97
126
|
super();
|
|
98
127
|
}
|
|
@@ -115,9 +144,19 @@ export class DyNTS_MemoryGuard extends DyNTS_SingletonServiceBase {
|
|
|
115
144
|
this.critPct = config?.heapCriticalThreshold ?? g.heapCriticalThreshold ?? 95;
|
|
116
145
|
this.recoveryMargin = config?.recoveryMargin ?? g.recoveryMargin ?? 10;
|
|
117
146
|
this.maxHistoryCount = config?.maxHistoryCount ?? g.maxHistoryCount ?? 100;
|
|
147
|
+
this.gcWarnFraction = config?.gcWarningFraction ?? g.gcWarningFraction ?? 0.40;
|
|
148
|
+
this.gcCritFraction = config?.gcCriticalFraction ?? g.gcCriticalFraction ?? 0.60;
|
|
149
|
+
this.exitOnSustainedCritical = config?.exitOnSustainedCritical ?? g.exitOnSustainedCritical ?? false;
|
|
150
|
+
this.sustainedCriticalPolls = config?.sustainedCriticalPolls ?? g.sustainedCriticalPolls ?? 3;
|
|
151
|
+
this.exitCode = config?.exitCode ?? g.exitCode ?? 137;
|
|
118
152
|
this.onCritical = config?.onCritical;
|
|
119
153
|
|
|
120
154
|
this.installed = true;
|
|
155
|
+
this.installGcObserver();
|
|
156
|
+
// Crash-handler (uncaughtException) — teljes-részletű error-entry a crash ELŐTT, majd tiszta exit.
|
|
157
|
+
if (config?.installCrashHandlers ?? g.installCrashHandlers ?? true) {
|
|
158
|
+
this.installCrashHandlers();
|
|
159
|
+
}
|
|
121
160
|
this.timer = setInterval((): void => { this.poll(); }, this.pollIntervalMs);
|
|
122
161
|
// unref(): a watchdog-timer NE tartsa életben a process-t önmagában (graceful
|
|
123
162
|
// exit-kor a Node ki tud lépni a függő interval ellenére is).
|
|
@@ -125,8 +164,10 @@ export class DyNTS_MemoryGuard extends DyNTS_SingletonServiceBase {
|
|
|
125
164
|
|
|
126
165
|
DyFM_Log.info(
|
|
127
166
|
`[DyNTS_MemoryGuard] installed — poll ${this.pollIntervalMs}ms, ` +
|
|
128
|
-
`warn ${this.warnPct}
|
|
129
|
-
|
|
167
|
+
`warn ${this.warnPct}%/${Math.round(this.gcWarnFraction * 100)}%GC, ` +
|
|
168
|
+
`crit ${this.critPct}%/${Math.round(this.gcCritFraction * 100)}%GC (heap limit ` +
|
|
169
|
+
`${Math.round(this.getHeapLimitBytes() / BYTES_PER_MB)}MB)` +
|
|
170
|
+
(this.exitOnSustainedCritical ? `, graceful-exit@${this.sustainedCriticalPolls} critical polls` : ''),
|
|
130
171
|
);
|
|
131
172
|
} catch (err: unknown) {
|
|
132
173
|
// Telepítési hiba SEM lehet fatal — a guard hiánya nem ér annyit, hogy a
|
|
@@ -151,27 +192,50 @@ export class DyNTS_MemoryGuard extends DyNTS_SingletonServiceBase {
|
|
|
151
192
|
|
|
152
193
|
const mu: NodeJS.MemoryUsage = process.memoryUsage();
|
|
153
194
|
const pct: number = (mu.heapUsed / limitBytes) * 100;
|
|
195
|
+
const gcFraction: number = this.recentGcFraction();
|
|
154
196
|
|
|
155
197
|
const rssMb: number = mu.rss / BYTES_PER_MB;
|
|
156
198
|
if (pct > this.peakHeapPct) { this.peakHeapPct = pct; }
|
|
157
199
|
if (rssMb > this.peakRssMb) { this.peakRssMb = rssMb; }
|
|
158
200
|
|
|
201
|
+
// A szintet a heap-% ÉS a GC-hányad közül a ROSSZABB dönti el (a GC-thrash a %-küszöb ALATT is OOM-ot jelez).
|
|
202
|
+
const heapCrit: boolean = pct >= this.critPct;
|
|
203
|
+
const gcCrit: boolean = gcFraction >= this.gcCritFraction;
|
|
204
|
+
const heapWarn: boolean = pct >= this.warnPct;
|
|
205
|
+
const gcWarn: boolean = gcFraction >= this.gcWarnFraction;
|
|
206
|
+
|
|
159
207
|
// Hiszterézis-állapotgép — esemény CSAK állapot-váltáskor.
|
|
160
208
|
const prev: DyNTS_MemoryGuard_State = this.state;
|
|
161
209
|
let next: DyNTS_MemoryGuard_State = prev;
|
|
162
210
|
|
|
163
|
-
if (
|
|
211
|
+
if (heapCrit || gcCrit) {
|
|
164
212
|
next = 'critical';
|
|
165
|
-
} else if (
|
|
213
|
+
} else if ((heapWarn || gcWarn) && prev === 'normal') {
|
|
166
214
|
next = 'warning';
|
|
167
|
-
} else if (pct <= this.warnPct - this.recoveryMargin) {
|
|
215
|
+
} else if (pct <= this.warnPct - this.recoveryMargin && gcFraction < this.gcWarnFraction) {
|
|
168
216
|
next = 'normal';
|
|
169
217
|
}
|
|
170
218
|
// Egyébként marad a jelenlegi állapot (hiszterézis-sáv) — nincs re-emit.
|
|
171
219
|
|
|
220
|
+
// Sustained-critical streak + opcionális graceful-exit (állapot-váltástól FÜGGETLENÜL számolva).
|
|
221
|
+
if (next === 'critical') {
|
|
222
|
+
this.criticalStreak += 1;
|
|
223
|
+
if (this.exitOnSustainedCritical && this.criticalStreak >= this.sustainedCriticalPolls) {
|
|
224
|
+
this.gracefulExit({ pct: pct, gcFraction: gcFraction, limitBytes: limitBytes, mu: mu });
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
this.criticalStreak = 0;
|
|
229
|
+
}
|
|
230
|
+
|
|
172
231
|
if (next === prev) { return; }
|
|
173
232
|
this.state = next;
|
|
174
233
|
|
|
234
|
+
const trigger: DyNTS_MemoryGuard_Event['trigger'] =
|
|
235
|
+
next === 'normal' ? 'recovery'
|
|
236
|
+
: (heapCrit || heapWarn) && (gcCrit || gcWarn) ? 'heap+gc'
|
|
237
|
+
: (gcCrit || gcWarn) ? 'gc' : 'heap';
|
|
238
|
+
|
|
175
239
|
const event: DyNTS_MemoryGuard_Event = {
|
|
176
240
|
level: next === 'normal' ? 'recovered' : next,
|
|
177
241
|
heapUsedMb: Math.round(mu.heapUsed / BYTES_PER_MB),
|
|
@@ -179,6 +243,8 @@ export class DyNTS_MemoryGuard extends DyNTS_SingletonServiceBase {
|
|
|
179
243
|
heapPct: Math.round(pct),
|
|
180
244
|
rssMb: Math.round(rssMb),
|
|
181
245
|
externalMb: Math.round((mu.external ?? 0) / BYTES_PER_MB),
|
|
246
|
+
gcFraction: Math.round(gcFraction * 100) / 100,
|
|
247
|
+
trigger: trigger,
|
|
182
248
|
at: new Date().toISOString(),
|
|
183
249
|
};
|
|
184
250
|
|
|
@@ -195,7 +261,8 @@ export class DyNTS_MemoryGuard extends DyNTS_SingletonServiceBase {
|
|
|
195
261
|
while (this.history.length > this.maxHistoryCount) { this.history.shift(); }
|
|
196
262
|
|
|
197
263
|
const summary: string =
|
|
198
|
-
`heap ${event.heapPct}% (${event.heapUsedMb}/${event.heapLimitMb}MB), rss ${event.rssMb}MB
|
|
264
|
+
`heap ${event.heapPct}% (${event.heapUsedMb}/${event.heapLimitMb}MB), rss ${event.rssMb}MB, ` +
|
|
265
|
+
`GC ${Math.round(event.gcFraction * 100)}% [${event.trigger}]`;
|
|
199
266
|
|
|
200
267
|
if (event.level === 'recovered') {
|
|
201
268
|
DyFM_Log.success(`[DyNTS_MemoryGuard] RECOVERED — ${summary}`);
|
|
@@ -235,6 +302,118 @@ export class DyNTS_MemoryGuard extends DyNTS_SingletonServiceBase {
|
|
|
235
302
|
}
|
|
236
303
|
}
|
|
237
304
|
|
|
305
|
+
/**
|
|
306
|
+
* A pillanatnyi heap-nyomás (heap-% + GC-hányad → szint) — a FOGYASZTÓK (pl. egy API-controller) ezzel
|
|
307
|
+
* gate-elhetik a nehéz műveleteket (load-shed). Olvasás-only, mellékhatás nélkül; nem igényli az install-t.
|
|
308
|
+
*/
|
|
309
|
+
pressure(): {
|
|
310
|
+
level: 'ok' | 'warning' | 'critical';
|
|
311
|
+
heapUsedMb: number; heapLimitMb: number; heapPct: number; rssMb: number; gcFraction: number;
|
|
312
|
+
} {
|
|
313
|
+
const limitBytes: number = this.getHeapLimitBytes();
|
|
314
|
+
const mu: NodeJS.MemoryUsage = process.memoryUsage();
|
|
315
|
+
const pct: number = limitBytes > 0 ? (mu.heapUsed / limitBytes) * 100 : 0;
|
|
316
|
+
const gcFraction: number = this.recentGcFraction();
|
|
317
|
+
const level: 'ok' | 'warning' | 'critical' =
|
|
318
|
+
(pct >= this.critPct || gcFraction >= this.gcCritFraction) ? 'critical'
|
|
319
|
+
: (pct >= this.warnPct || gcFraction >= this.gcWarnFraction) ? 'warning' : 'ok';
|
|
320
|
+
return {
|
|
321
|
+
level: level,
|
|
322
|
+
heapUsedMb: Math.round(mu.heapUsed / BYTES_PER_MB),
|
|
323
|
+
heapLimitMb: Math.round(limitBytes / BYTES_PER_MB),
|
|
324
|
+
heapPct: Math.round(pct),
|
|
325
|
+
rssMb: Math.round(mu.rss / BYTES_PER_MB),
|
|
326
|
+
gcFraction: Math.round(gcFraction * 100) / 100,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** `true`, ha a NEHÉZ műveleteket le kell shed-elni (critical nyomás) — a fogyasztó load-shed gate-jének. */
|
|
331
|
+
shouldShedLoad(): boolean {
|
|
332
|
+
return this.installed && this.pressure().level === 'critical';
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** A GC-hányad az utolsó `pollIntervalMs` ablakban (GC-ms / ablak-ms; clamp [0..1]). Nincs GC-observer → 0. */
|
|
336
|
+
private recentGcFraction(): number {
|
|
337
|
+
const windowMs: number = this.pollIntervalMs > 0 ? this.pollIntervalMs : 10000;
|
|
338
|
+
const cutoff: number = Date.now() - windowMs;
|
|
339
|
+
this.gcEvents = this.gcEvents.filter((event: { at: number; ms: number }): boolean => event.at >= cutoff);
|
|
340
|
+
const gcMs: number = this.gcEvents.reduce((sum: number, event: { at: number; ms: number }): number => sum + event.ms, 0);
|
|
341
|
+
return Math.min(gcMs / windowMs, 1);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** A 'gc' perf-entry-k figyelője — a GC-ben töltött időt gyűjti a gördülő ablakhoz. Best-effort (nem kritikus). */
|
|
345
|
+
private installGcObserver(): void {
|
|
346
|
+
try {
|
|
347
|
+
this.gcObserver = new PerformanceObserver((list): void => {
|
|
348
|
+
const now: number = Date.now();
|
|
349
|
+
for (const entry of list.getEntries()) {
|
|
350
|
+
this.gcEvents.push({ at: now, ms: entry.duration });
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
this.gcObserver.observe({ entryTypes: ['gc'] });
|
|
354
|
+
} catch (err: unknown) {
|
|
355
|
+
// A GC-observer hiánya nem kritikus — a heap-%-jel marad. Best-effort.
|
|
356
|
+
DyFM_Log.warn('[DyNTS_MemoryGuard] gc-observer install failed (non-fatal):', err);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Process-szintű `uncaughtException` crash-handler: a (különben néma) crash ELŐTT TELJES-RÉSZLETŰ error-entry
|
|
362
|
+
* (message + stack + memória-snapshot) az error-sinkbe, majd tiszta exit (a wrapper/restart-policy újraindít).
|
|
363
|
+
* Az `unhandledRejection`-t a base App már rögzíti; ez az eddig-fedetlen `uncaughtException`-t fedi le.
|
|
364
|
+
*/
|
|
365
|
+
private installCrashHandlers(): void {
|
|
366
|
+
this.crashHandler = (error: Error): void => {
|
|
367
|
+
try {
|
|
368
|
+
const mu: NodeJS.MemoryUsage = process.memoryUsage();
|
|
369
|
+
DyFM_Log.H_error('[DyNTS_MemoryGuard] FATAL uncaughtException:', error?.stack ?? error);
|
|
370
|
+
DyNTS_GlobalService.globalErrorHandler?.(
|
|
371
|
+
new DyFM_Error({
|
|
372
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName ?? 'DyNTS'}|DyNTS-MG0-UNCAUGHT`,
|
|
373
|
+
message: `Uncaught Exception (process-fatal): ${error?.message ?? String(error)}`,
|
|
374
|
+
error: error,
|
|
375
|
+
additionalContent: {
|
|
376
|
+
stack: error?.stack,
|
|
377
|
+
heapUsedMb: Math.round(mu.heapUsed / BYTES_PER_MB),
|
|
378
|
+
rssMb: Math.round(mu.rss / BYTES_PER_MB),
|
|
379
|
+
peakHeapPct: Math.round(this.peakHeapPct),
|
|
380
|
+
recentMemoryGuardEvents: this.history.slice(-5),
|
|
381
|
+
},
|
|
382
|
+
systemVersion: DyNTS_global_settings.systemVersion,
|
|
383
|
+
level: DyFM_ErrorLevel.critical,
|
|
384
|
+
}),
|
|
385
|
+
);
|
|
386
|
+
} catch {
|
|
387
|
+
// a rögzítés se buktasson — best-effort.
|
|
388
|
+
}
|
|
389
|
+
// uncaughtException → a process undefined állapotban van: rögzítés UTÁN tiszta exit (a log/sink flush-re haladék).
|
|
390
|
+
setTimeout((): void => { process.exit(1); }, 250).unref?.();
|
|
391
|
+
};
|
|
392
|
+
process.on('uncaughtException', this.crashHandler);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/** Tartós-critical graceful-exit: végső error-entry + tiszta exit (a wrapper újraindít a kriptikus 134 helyett). */
|
|
396
|
+
private gracefulExit(set: { pct: number; gcFraction: number; limitBytes: number; mu: NodeJS.MemoryUsage }): void {
|
|
397
|
+
const summary: string =
|
|
398
|
+
`heap ${Math.round(set.pct)}% (${Math.round(set.mu.heapUsed / BYTES_PER_MB)}/` +
|
|
399
|
+
`${Math.round(set.limitBytes / BYTES_PER_MB)}MB), GC ${Math.round(set.gcFraction * 100)}%`;
|
|
400
|
+
DyFM_Log.H_error(`[DyNTS_MemoryGuard] SUSTAINED CRITICAL — ${summary} — graceful exit(${this.exitCode}) a kriptikus OOM (exit 134) helyett.`);
|
|
401
|
+
try {
|
|
402
|
+
DyNTS_GlobalService.globalErrorHandler?.(
|
|
403
|
+
new DyFM_Error({
|
|
404
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName ?? 'DyNTS'}|DyNTS-MG0-GRACEFUL-EXIT`,
|
|
405
|
+
message: `Sustained critical heap pressure (${this.criticalStreak} polls) — graceful exit to let the wrapper/restart-policy recover. ${summary}.`,
|
|
406
|
+
additionalContent: { peakHeapPct: Math.round(this.peakHeapPct), peakRssMb: Math.round(this.peakRssMb), recentEvents: this.history.slice(-5) },
|
|
407
|
+
systemVersion: DyNTS_global_settings.systemVersion,
|
|
408
|
+
level: DyFM_ErrorLevel.critical,
|
|
409
|
+
}),
|
|
410
|
+
);
|
|
411
|
+
} catch {
|
|
412
|
+
// best-effort
|
|
413
|
+
}
|
|
414
|
+
setTimeout((): void => { process.exit(this.exitCode); }, 250).unref?.();
|
|
415
|
+
}
|
|
416
|
+
|
|
238
417
|
/** A megőrzött események (legrégebbi → legújabb). Csak olvasásra. */
|
|
239
418
|
getHistory(): DyNTS_MemoryGuard_Event[] {
|
|
240
419
|
return this.history.slice();
|
|
@@ -271,11 +450,21 @@ export class DyNTS_MemoryGuard extends DyNTS_SingletonServiceBase {
|
|
|
271
450
|
clearInterval(this.timer);
|
|
272
451
|
this.timer = null;
|
|
273
452
|
}
|
|
453
|
+
if (this.gcObserver) {
|
|
454
|
+
try { this.gcObserver.disconnect(); } catch { /* best-effort */ }
|
|
455
|
+
this.gcObserver = null;
|
|
456
|
+
}
|
|
457
|
+
if (this.crashHandler) {
|
|
458
|
+
try { process.removeListener('uncaughtException', this.crashHandler); } catch { /* best-effort */ }
|
|
459
|
+
this.crashHandler = null;
|
|
460
|
+
}
|
|
274
461
|
this.installed = false;
|
|
275
462
|
this.state = 'normal';
|
|
276
463
|
this.history.length = 0;
|
|
277
464
|
this.peakHeapPct = 0;
|
|
278
465
|
this.peakRssMb = 0;
|
|
466
|
+
this.gcEvents = [];
|
|
467
|
+
this.criticalStreak = 0;
|
|
279
468
|
this.onCritical = undefined;
|
|
280
469
|
}
|
|
281
470
|
}
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
import { DyNTS_Service_Collection } from './service-collection.service';
|
|
3
|
-
|
|
4
|
-
class TestService {
|
|
5
|
-
name: string;
|
|
6
|
-
constructor(name: string) {
|
|
7
|
-
this.name = name;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
describe('| DyNTS_Service_Collection', () => {
|
|
12
|
-
it('| should be a singleton instance', () => {
|
|
13
|
-
class TestCollection extends DyNTS_Service_Collection<TestService> {
|
|
14
|
-
static getInstance(): TestCollection {
|
|
15
|
-
return TestCollection.getSingletonInstance();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const instance1 = TestCollection.getInstance();
|
|
20
|
-
const instance2 = TestCollection.getInstance();
|
|
21
|
-
|
|
22
|
-
expect(instance1).toBe(instance2);
|
|
23
|
-
expect(instance1).toBeInstanceOf(TestCollection);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('| should allow dynamic property assignment', () => {
|
|
27
|
-
class TestCollection extends DyNTS_Service_Collection<TestService> {
|
|
28
|
-
static getInstance(): TestCollection {
|
|
29
|
-
return TestCollection.getSingletonInstance();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const collection = TestCollection.getInstance();
|
|
34
|
-
const service1 = new TestService('service1');
|
|
35
|
-
const service2 = new TestService('service2');
|
|
36
|
-
|
|
37
|
-
collection['service1'] = service1;
|
|
38
|
-
collection['service2'] = service2;
|
|
39
|
-
|
|
40
|
-
expect(collection['service1']).toBe(service1);
|
|
41
|
-
expect(collection['service2']).toBe(service2);
|
|
42
|
-
expect(collection['service1'].name).toBe('service1');
|
|
43
|
-
expect(collection['service2'].name).toBe('service2');
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
1
|
+
|
|
2
|
+
import { DyNTS_Service_Collection } from './service-collection.service';
|
|
3
|
+
|
|
4
|
+
class TestService {
|
|
5
|
+
name: string;
|
|
6
|
+
constructor(name: string) {
|
|
7
|
+
this.name = name;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe('| DyNTS_Service_Collection', () => {
|
|
12
|
+
it('| should be a singleton instance', () => {
|
|
13
|
+
class TestCollection extends DyNTS_Service_Collection<TestService> {
|
|
14
|
+
static getInstance(): TestCollection {
|
|
15
|
+
return TestCollection.getSingletonInstance();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const instance1 = TestCollection.getInstance();
|
|
20
|
+
const instance2 = TestCollection.getInstance();
|
|
21
|
+
|
|
22
|
+
expect(instance1).toBe(instance2);
|
|
23
|
+
expect(instance1).toBeInstanceOf(TestCollection);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('| should allow dynamic property assignment', () => {
|
|
27
|
+
class TestCollection extends DyNTS_Service_Collection<TestService> {
|
|
28
|
+
static getInstance(): TestCollection {
|
|
29
|
+
return TestCollection.getSingletonInstance();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const collection = TestCollection.getInstance();
|
|
34
|
+
const service1 = new TestService('service1');
|
|
35
|
+
const service2 = new TestService('service2');
|
|
36
|
+
|
|
37
|
+
collection['service1'] = service1;
|
|
38
|
+
collection['service2'] = service2;
|
|
39
|
+
|
|
40
|
+
expect(collection['service1']).toBe(service1);
|
|
41
|
+
expect(collection['service2']).toBe(service2);
|
|
42
|
+
expect(collection['service1'].name).toBe('service1');
|
|
43
|
+
expect(collection['service2'].name).toBe('service2');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import { DyNTS_SingletonServiceBase } from '../base/singleton.service-base';
|
|
3
|
-
|
|
4
|
-
export class DyNTS_Service_Collection<T> extends DyNTS_SingletonServiceBase {
|
|
5
|
-
[service: string]: T;
|
|
6
|
-
}
|
|
1
|
+
|
|
2
|
+
import { DyNTS_SingletonServiceBase } from '../base/singleton.service-base';
|
|
3
|
+
|
|
4
|
+
export class DyNTS_Service_Collection<T> extends DyNTS_SingletonServiceBase {
|
|
5
|
+
[service: string]: T;
|
|
6
|
+
}
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
import { DyFM_HttpCallType } from '@futdevpro/fsm-dynamo';
|
|
3
|
-
|
|
4
|
-
import { DyNTS_Endpoint_Params } from '../../_models/control-models/endpoint-params.control-model';
|
|
5
|
-
import { DyNTS_Controller } from './controller.service';
|
|
6
|
-
|
|
7
|
-
class TestController extends DyNTS_Controller {
|
|
8
|
-
setupEndpoints(): void {
|
|
9
|
-
this.endpoints = [
|
|
10
|
-
new DyNTS_Endpoint_Params({
|
|
11
|
-
name: 'testEndpoint',
|
|
12
|
-
type: DyFM_HttpCallType.get,
|
|
13
|
-
endpoint: '/test-endpoint',
|
|
14
|
-
preProcesses: [],
|
|
15
|
-
tasks: [
|
|
16
|
-
async (req: any, res: any) => {
|
|
17
|
-
res.send({ message: 'Test successful' });
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
}),
|
|
21
|
-
];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
static getInstance(): TestController {
|
|
25
|
-
return new TestController();
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
describe('| DyNTS_Controller', () => {
|
|
30
|
-
let controller: TestController;
|
|
31
|
-
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
controller = TestController.getInstance();
|
|
34
|
-
controller.setupEndpoints();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('| should initialize endpoints correctly', () => {
|
|
38
|
-
expect(controller.endpoints.length).toBe(1);
|
|
39
|
-
expect(controller.endpoints[0].name).toBe('testEndpoint');
|
|
40
|
-
expect(controller.endpoints[0].endpoint).toBe('/test-endpoint');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
/* it('| should execute task and send response', async () => {
|
|
44
|
-
const req = {};
|
|
45
|
-
const res = {
|
|
46
|
-
send: jasmine.createSpy('send'),
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
await controller.endpoints[0].tasks[0](req, res);
|
|
50
|
-
|
|
51
|
-
expect(res.send).toHaveBeenCalledWith({ message: 'Test successful' });
|
|
52
|
-
}); */
|
|
53
|
-
});
|
|
1
|
+
|
|
2
|
+
import { DyFM_HttpCallType } from '@futdevpro/fsm-dynamo';
|
|
3
|
+
|
|
4
|
+
import { DyNTS_Endpoint_Params } from '../../_models/control-models/endpoint-params.control-model';
|
|
5
|
+
import { DyNTS_Controller } from './controller.service';
|
|
6
|
+
|
|
7
|
+
class TestController extends DyNTS_Controller {
|
|
8
|
+
setupEndpoints(): void {
|
|
9
|
+
this.endpoints = [
|
|
10
|
+
new DyNTS_Endpoint_Params({
|
|
11
|
+
name: 'testEndpoint',
|
|
12
|
+
type: DyFM_HttpCallType.get,
|
|
13
|
+
endpoint: '/test-endpoint',
|
|
14
|
+
preProcesses: [],
|
|
15
|
+
tasks: [
|
|
16
|
+
async (req: any, res: any) => {
|
|
17
|
+
res.send({ message: 'Test successful' });
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
}),
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static getInstance(): TestController {
|
|
25
|
+
return new TestController();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('| DyNTS_Controller', () => {
|
|
30
|
+
let controller: TestController;
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
controller = TestController.getInstance();
|
|
34
|
+
controller.setupEndpoints();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('| should initialize endpoints correctly', () => {
|
|
38
|
+
expect(controller.endpoints.length).toBe(1);
|
|
39
|
+
expect(controller.endpoints[0].name).toBe('testEndpoint');
|
|
40
|
+
expect(controller.endpoints[0].endpoint).toBe('/test-endpoint');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/* it('| should execute task and send response', async () => {
|
|
44
|
+
const req = {};
|
|
45
|
+
const res = {
|
|
46
|
+
send: jasmine.createSpy('send'),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
await controller.endpoints[0].tasks[0](req, res);
|
|
50
|
+
|
|
51
|
+
expect(res.send).toHaveBeenCalledWith({ message: 'Test successful' });
|
|
52
|
+
}); */
|
|
53
|
+
});
|