@zyno-io/dk-server-foundation 26.216.430
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/LICENSE +21 -0
- package/README.md +458 -0
- package/dist/devconsole/assets/index-CKF3C3kv.css +1 -0
- package/dist/devconsole/assets/index-CsHdomhM.js +27 -0
- package/dist/devconsole/index.html +13 -0
- package/dist/resources/proto/generated/devconsole/devconsole.d.ts +320 -0
- package/dist/resources/proto/generated/devconsole/devconsole.d.ts.map +1 -0
- package/dist/resources/proto/generated/devconsole/devconsole.js +3751 -0
- package/dist/resources/proto/generated/devconsole/devconsole.js.map +1 -0
- package/dist/src/app/base.d.ts +36 -0
- package/dist/src/app/base.d.ts.map +1 -0
- package/dist/src/app/base.js +240 -0
- package/dist/src/app/base.js.map +1 -0
- package/dist/src/app/config.d.ts +90 -0
- package/dist/src/app/config.d.ts.map +1 -0
- package/dist/src/app/config.js +33 -0
- package/dist/src/app/config.js.map +1 -0
- package/dist/src/app/config.loader.d.ts +14 -0
- package/dist/src/app/config.loader.d.ts.map +1 -0
- package/dist/src/app/config.loader.js +67 -0
- package/dist/src/app/config.loader.js.map +1 -0
- package/dist/src/app/const.d.ts +3 -0
- package/dist/src/app/const.d.ts.map +1 -0
- package/dist/src/app/const.js +6 -0
- package/dist/src/app/const.js.map +1 -0
- package/dist/src/app/dev.d.ts +7 -0
- package/dist/src/app/dev.d.ts.map +1 -0
- package/dist/src/app/dev.js +105 -0
- package/dist/src/app/dev.js.map +1 -0
- package/dist/src/app/index.d.ts +7 -0
- package/dist/src/app/index.d.ts.map +1 -0
- package/dist/src/app/index.js +12 -0
- package/dist/src/app/index.js.map +1 -0
- package/dist/src/app/openapi.d.ts +4 -0
- package/dist/src/app/openapi.d.ts.map +1 -0
- package/dist/src/app/openapi.js +6 -0
- package/dist/src/app/openapi.js.map +1 -0
- package/dist/src/app/resolver.d.ts +11 -0
- package/dist/src/app/resolver.d.ts.map +1 -0
- package/dist/src/app/resolver.js +60 -0
- package/dist/src/app/resolver.js.map +1 -0
- package/dist/src/app/shutdown.d.ts +12 -0
- package/dist/src/app/shutdown.d.ts.map +1 -0
- package/dist/src/app/shutdown.js +63 -0
- package/dist/src/app/shutdown.js.map +1 -0
- package/dist/src/app/state.d.ts +16 -0
- package/dist/src/app/state.d.ts.map +1 -0
- package/dist/src/app/state.js +12 -0
- package/dist/src/app/state.js.map +1 -0
- package/dist/src/auth/index.d.ts +3 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/index.js +6 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/jwt.d.ts +76 -0
- package/dist/src/auth/jwt.d.ts.map +1 -0
- package/dist/src/auth/jwt.js +218 -0
- package/dist/src/auth/jwt.js.map +1 -0
- package/dist/src/auth/provider.d.ts +15 -0
- package/dist/src/auth/provider.d.ts.map +1 -0
- package/dist/src/auth/provider.js +50 -0
- package/dist/src/auth/provider.js.map +1 -0
- package/dist/src/cli/dksf-dev.d.ts +3 -0
- package/dist/src/cli/dksf-dev.d.ts.map +1 -0
- package/dist/src/cli/dksf-dev.js +408 -0
- package/dist/src/cli/dksf-dev.js.map +1 -0
- package/dist/src/cli/dksf-gen-proto.d.ts +3 -0
- package/dist/src/cli/dksf-gen-proto.d.ts.map +1 -0
- package/dist/src/cli/dksf-gen-proto.js +164 -0
- package/dist/src/cli/dksf-gen-proto.js.map +1 -0
- package/dist/src/cli/dksf-install.d.ts +3 -0
- package/dist/src/cli/dksf-install.d.ts.map +1 -0
- package/dist/src/cli/dksf-install.js +10 -0
- package/dist/src/cli/dksf-install.js.map +1 -0
- package/dist/src/cli/dksf-test.d.ts +3 -0
- package/dist/src/cli/dksf-test.d.ts.map +1 -0
- package/dist/src/cli/dksf-test.js +78 -0
- package/dist/src/cli/dksf-test.js.map +1 -0
- package/dist/src/cli/dksf-update.d.ts +3 -0
- package/dist/src/cli/dksf-update.d.ts.map +1 -0
- package/dist/src/cli/dksf-update.js +86 -0
- package/dist/src/cli/dksf-update.js.map +1 -0
- package/dist/src/database/common.d.ts +84 -0
- package/dist/src/database/common.d.ts.map +1 -0
- package/dist/src/database/common.js +380 -0
- package/dist/src/database/common.js.map +1 -0
- package/dist/src/database/dialect.d.ts +10 -0
- package/dist/src/database/dialect.d.ts.map +1 -0
- package/dist/src/database/dialect.js +56 -0
- package/dist/src/database/dialect.js.map +1 -0
- package/dist/src/database/entity.d.ts +62 -0
- package/dist/src/database/entity.d.ts.map +1 -0
- package/dist/src/database/entity.js +198 -0
- package/dist/src/database/entity.js.map +1 -0
- package/dist/src/database/index.d.ts +8 -0
- package/dist/src/database/index.d.ts.map +1 -0
- package/dist/src/database/index.js +15 -0
- package/dist/src/database/index.js.map +1 -0
- package/dist/src/database/migration/MigrationResetCommand.d.ts +9 -0
- package/dist/src/database/migration/MigrationResetCommand.d.ts.map +1 -0
- package/dist/src/database/migration/MigrationResetCommand.js +75 -0
- package/dist/src/database/migration/MigrationResetCommand.js.map +1 -0
- package/dist/src/database/migration/MigrationRunCommand.d.ts +11 -0
- package/dist/src/database/migration/MigrationRunCommand.d.ts.map +1 -0
- package/dist/src/database/migration/MigrationRunCommand.js +118 -0
- package/dist/src/database/migration/MigrationRunCommand.js.map +1 -0
- package/dist/src/database/migration/characters.d.ts +14 -0
- package/dist/src/database/migration/characters.d.ts.map +1 -0
- package/dist/src/database/migration/characters.js +56 -0
- package/dist/src/database/migration/characters.js.map +1 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.d.ts +11 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.d.ts.map +1 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.js +106 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.js.map +1 -0
- package/dist/src/database/migration/create/comparator.d.ts +3 -0
- package/dist/src/database/migration/create/comparator.d.ts.map +1 -0
- package/dist/src/database/migration/create/comparator.js +408 -0
- package/dist/src/database/migration/create/comparator.js.map +1 -0
- package/dist/src/database/migration/create/db-reader.d.ts +5 -0
- package/dist/src/database/migration/create/db-reader.d.ts.map +1 -0
- package/dist/src/database/migration/create/db-reader.js +473 -0
- package/dist/src/database/migration/create/db-reader.js.map +1 -0
- package/dist/src/database/migration/create/ddl-generator.d.ts +3 -0
- package/dist/src/database/migration/create/ddl-generator.d.ts.map +1 -0
- package/dist/src/database/migration/create/ddl-generator.js +725 -0
- package/dist/src/database/migration/create/ddl-generator.js.map +1 -0
- package/dist/src/database/migration/create/entity-reader.d.ts +4 -0
- package/dist/src/database/migration/create/entity-reader.d.ts.map +1 -0
- package/dist/src/database/migration/create/entity-reader.js +417 -0
- package/dist/src/database/migration/create/entity-reader.js.map +1 -0
- package/dist/src/database/migration/create/file-generator.d.ts +3 -0
- package/dist/src/database/migration/create/file-generator.d.ts.map +1 -0
- package/dist/src/database/migration/create/file-generator.js +62 -0
- package/dist/src/database/migration/create/file-generator.js.map +1 -0
- package/dist/src/database/migration/create/prompt.d.ts +4 -0
- package/dist/src/database/migration/create/prompt.d.ts.map +1 -0
- package/dist/src/database/migration/create/prompt.js +55 -0
- package/dist/src/database/migration/create/prompt.js.map +1 -0
- package/dist/src/database/migration/create/schema-model.d.ts +109 -0
- package/dist/src/database/migration/create/schema-model.d.ts.map +1 -0
- package/dist/src/database/migration/create/schema-model.js +24 -0
- package/dist/src/database/migration/create/schema-model.js.map +1 -0
- package/dist/src/database/migration/helpers.d.ts +3 -0
- package/dist/src/database/migration/helpers.d.ts.map +1 -0
- package/dist/src/database/migration/helpers.js +13 -0
- package/dist/src/database/migration/helpers.js.map +1 -0
- package/dist/src/database/migration/index.d.ts +9 -0
- package/dist/src/database/migration/index.d.ts.map +1 -0
- package/dist/src/database/migration/index.js +43 -0
- package/dist/src/database/migration/index.js.map +1 -0
- package/dist/src/database/migration/migration.entity.d.ts +8 -0
- package/dist/src/database/migration/migration.entity.d.ts.map +1 -0
- package/dist/src/database/migration/migration.entity.js +16 -0
- package/dist/src/database/migration/migration.entity.js.map +1 -0
- package/dist/src/database/mysql.d.ts +16 -0
- package/dist/src/database/mysql.d.ts.map +1 -0
- package/dist/src/database/mysql.js +140 -0
- package/dist/src/database/mysql.js.map +1 -0
- package/dist/src/database/postgres.d.ts +16 -0
- package/dist/src/database/postgres.d.ts.map +1 -0
- package/dist/src/database/postgres.js +91 -0
- package/dist/src/database/postgres.js.map +1 -0
- package/dist/src/database/types.d.ts +21 -0
- package/dist/src/database/types.d.ts.map +1 -0
- package/dist/src/database/types.js +27 -0
- package/dist/src/database/types.js.map +1 -0
- package/dist/src/devconsole/devconsole.controller.d.ts +7 -0
- package/dist/src/devconsole/devconsole.controller.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.controller.js +82 -0
- package/dist/src/devconsole/devconsole.controller.js.map +1 -0
- package/dist/src/devconsole/devconsole.middleware.d.ts +12 -0
- package/dist/src/devconsole/devconsole.middleware.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.middleware.js +28 -0
- package/dist/src/devconsole/devconsole.middleware.js.map +1 -0
- package/dist/src/devconsole/devconsole.srpc.d.ts +14 -0
- package/dist/src/devconsole/devconsole.srpc.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.srpc.js +94 -0
- package/dist/src/devconsole/devconsole.srpc.js.map +1 -0
- package/dist/src/devconsole/devconsole.store.d.ts +101 -0
- package/dist/src/devconsole/devconsole.store.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.store.js +125 -0
- package/dist/src/devconsole/devconsole.store.js.map +1 -0
- package/dist/src/devconsole/devconsole.ws.d.ts +18 -0
- package/dist/src/devconsole/devconsole.ws.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.ws.js +470 -0
- package/dist/src/devconsole/devconsole.ws.js.map +1 -0
- package/dist/src/devconsole/index.d.ts +2 -0
- package/dist/src/devconsole/index.d.ts.map +1 -0
- package/dist/src/devconsole/index.js +6 -0
- package/dist/src/devconsole/index.js.map +1 -0
- package/dist/src/devconsole/patches.d.ts +6 -0
- package/dist/src/devconsole/patches.d.ts.map +1 -0
- package/dist/src/devconsole/patches.js +397 -0
- package/dist/src/devconsole/patches.js.map +1 -0
- package/dist/src/health/health.module.d.ts +6 -0
- package/dist/src/health/health.module.d.ts.map +1 -0
- package/dist/src/health/health.module.js +32 -0
- package/dist/src/health/health.module.js.map +1 -0
- package/dist/src/health/healthcheck.controller.d.ts +10 -0
- package/dist/src/health/healthcheck.controller.d.ts.map +1 -0
- package/dist/src/health/healthcheck.controller.js +30 -0
- package/dist/src/health/healthcheck.controller.js.map +1 -0
- package/dist/src/health/healthcheck.service.d.ts +13 -0
- package/dist/src/health/healthcheck.service.d.ts.map +1 -0
- package/dist/src/health/healthcheck.service.js +33 -0
- package/dist/src/health/healthcheck.service.js.map +1 -0
- package/dist/src/health/index.d.ts +3 -0
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/health/index.js +6 -0
- package/dist/src/health/index.js.map +1 -0
- package/dist/src/helpers/async/context.d.ts +11 -0
- package/dist/src/helpers/async/context.d.ts.map +1 -0
- package/dist/src/helpers/async/context.js +75 -0
- package/dist/src/helpers/async/context.js.map +1 -0
- package/dist/src/helpers/async/process.d.ts +16 -0
- package/dist/src/helpers/async/process.d.ts.map +1 -0
- package/dist/src/helpers/async/process.js +44 -0
- package/dist/src/helpers/async/process.js.map +1 -0
- package/dist/src/helpers/async/promise.d.ts +5 -0
- package/dist/src/helpers/async/promise.d.ts.map +1 -0
- package/dist/src/helpers/async/promise.js +27 -0
- package/dist/src/helpers/async/promise.js.map +1 -0
- package/dist/src/helpers/data/array.d.ts +3 -0
- package/dist/src/helpers/data/array.d.ts.map +1 -0
- package/dist/src/helpers/data/array.js +17 -0
- package/dist/src/helpers/data/array.js.map +1 -0
- package/dist/src/helpers/data/objects.d.ts +12 -0
- package/dist/src/helpers/data/objects.d.ts.map +1 -0
- package/dist/src/helpers/data/objects.js +75 -0
- package/dist/src/helpers/data/objects.js.map +1 -0
- package/dist/src/helpers/data/serialization.d.ts +4 -0
- package/dist/src/helpers/data/serialization.d.ts.map +1 -0
- package/dist/src/helpers/data/serialization.js +15 -0
- package/dist/src/helpers/data/serialization.js.map +1 -0
- package/dist/src/helpers/data/transformer.d.ts +13 -0
- package/dist/src/helpers/data/transformer.d.ts.map +1 -0
- package/dist/src/helpers/data/transformer.js +55 -0
- package/dist/src/helpers/data/transformer.js.map +1 -0
- package/dist/src/helpers/framework/decorators.d.ts +5 -0
- package/dist/src/helpers/framework/decorators.d.ts.map +1 -0
- package/dist/src/helpers/framework/decorators.js +39 -0
- package/dist/src/helpers/framework/decorators.js.map +1 -0
- package/dist/src/helpers/framework/event.d.ts +3 -0
- package/dist/src/helpers/framework/event.d.ts.map +1 -0
- package/dist/src/helpers/framework/event.js +20 -0
- package/dist/src/helpers/framework/event.js.map +1 -0
- package/dist/src/helpers/framework/injection.d.ts +7 -0
- package/dist/src/helpers/framework/injection.d.ts.map +1 -0
- package/dist/src/helpers/framework/injection.js +52 -0
- package/dist/src/helpers/framework/injection.js.map +1 -0
- package/dist/src/helpers/index.d.ts +22 -0
- package/dist/src/helpers/index.d.ts.map +1 -0
- package/dist/src/helpers/index.js +32 -0
- package/dist/src/helpers/index.js.map +1 -0
- package/dist/src/helpers/io/package.d.ts +5 -0
- package/dist/src/helpers/io/package.d.ts.map +1 -0
- package/dist/src/helpers/io/package.js +31 -0
- package/dist/src/helpers/io/package.js.map +1 -0
- package/dist/src/helpers/io/stream.d.ts +18 -0
- package/dist/src/helpers/io/stream.d.ts.map +1 -0
- package/dist/src/helpers/io/stream.js +91 -0
- package/dist/src/helpers/io/stream.js.map +1 -0
- package/dist/src/helpers/redis/broadcast.d.ts +13 -0
- package/dist/src/helpers/redis/broadcast.d.ts.map +1 -0
- package/dist/src/helpers/redis/broadcast.js +100 -0
- package/dist/src/helpers/redis/broadcast.js.map +1 -0
- package/dist/src/helpers/redis/cache.d.ts +7 -0
- package/dist/src/helpers/redis/cache.d.ts.map +1 -0
- package/dist/src/helpers/redis/cache.js +28 -0
- package/dist/src/helpers/redis/cache.js.map +1 -0
- package/dist/src/helpers/redis/mutex.d.ts +24 -0
- package/dist/src/helpers/redis/mutex.d.ts.map +1 -0
- package/dist/src/helpers/redis/mutex.js +240 -0
- package/dist/src/helpers/redis/mutex.js.map +1 -0
- package/dist/src/helpers/redis/redis.d.ts +11 -0
- package/dist/src/helpers/redis/redis.d.ts.map +1 -0
- package/dist/src/helpers/redis/redis.js +59 -0
- package/dist/src/helpers/redis/redis.js.map +1 -0
- package/dist/src/helpers/security/crypto.d.ts +26 -0
- package/dist/src/helpers/security/crypto.d.ts.map +1 -0
- package/dist/src/helpers/security/crypto.js +121 -0
- package/dist/src/helpers/security/crypto.js.map +1 -0
- package/dist/src/helpers/security/validation.d.ts +4 -0
- package/dist/src/helpers/security/validation.d.ts.map +1 -0
- package/dist/src/helpers/security/validation.js +25 -0
- package/dist/src/helpers/security/validation.js.map +1 -0
- package/dist/src/helpers/utils/date.d.ts +4 -0
- package/dist/src/helpers/utils/date.d.ts.map +1 -0
- package/dist/src/helpers/utils/date.js +23 -0
- package/dist/src/helpers/utils/date.js.map +1 -0
- package/dist/src/helpers/utils/error.d.ts +24 -0
- package/dist/src/helpers/utils/error.d.ts.map +1 -0
- package/dist/src/helpers/utils/error.js +168 -0
- package/dist/src/helpers/utils/error.js.map +1 -0
- package/dist/src/helpers/utils/jsx.d.ts +3 -0
- package/dist/src/helpers/utils/jsx.d.ts.map +1 -0
- package/dist/src/helpers/utils/jsx.js +13 -0
- package/dist/src/helpers/utils/jsx.js.map +1 -0
- package/dist/src/helpers/utils/uuid.d.ts +3 -0
- package/dist/src/helpers/utils/uuid.d.ts.map +1 -0
- package/dist/src/helpers/utils/uuid.js +14 -0
- package/dist/src/helpers/utils/uuid.js.map +1 -0
- package/dist/src/http/auth.d.ts +46 -0
- package/dist/src/http/auth.d.ts.map +1 -0
- package/dist/src/http/auth.js +162 -0
- package/dist/src/http/auth.js.map +1 -0
- package/dist/src/http/context.d.ts +5 -0
- package/dist/src/http/context.d.ts.map +1 -0
- package/dist/src/http/context.js +22 -0
- package/dist/src/http/context.js.map +1 -0
- package/dist/src/http/cors.d.ts +36 -0
- package/dist/src/http/cors.d.ts.map +1 -0
- package/dist/src/http/cors.js +171 -0
- package/dist/src/http/cors.js.map +1 -0
- package/dist/src/http/errors.d.ts +3 -0
- package/dist/src/http/errors.d.ts.map +1 -0
- package/dist/src/http/errors.js +10 -0
- package/dist/src/http/errors.js.map +1 -0
- package/dist/src/http/index.d.ts +24 -0
- package/dist/src/http/index.d.ts.map +1 -0
- package/dist/src/http/index.js +25 -0
- package/dist/src/http/index.js.map +1 -0
- package/dist/src/http/kernel.d.ts +17 -0
- package/dist/src/http/kernel.d.ts.map +1 -0
- package/dist/src/http/kernel.js +133 -0
- package/dist/src/http/kernel.js.map +1 -0
- package/dist/src/http/middleware.d.ts +12 -0
- package/dist/src/http/middleware.d.ts.map +1 -0
- package/dist/src/http/middleware.js +61 -0
- package/dist/src/http/middleware.js.map +1 -0
- package/dist/src/http/overrides.d.ts +2 -0
- package/dist/src/http/overrides.d.ts.map +1 -0
- package/dist/src/http/overrides.js +19 -0
- package/dist/src/http/overrides.js.map +1 -0
- package/dist/src/http/store.d.ts +33 -0
- package/dist/src/http/store.d.ts.map +1 -0
- package/dist/src/http/store.js +102 -0
- package/dist/src/http/store.js.map +1 -0
- package/dist/src/http/uploads.d.ts +7 -0
- package/dist/src/http/uploads.d.ts.map +1 -0
- package/dist/src/http/uploads.js +8 -0
- package/dist/src/http/uploads.js.map +1 -0
- package/dist/src/http/workflow.d.ts +18 -0
- package/dist/src/http/workflow.d.ts.map +1 -0
- package/dist/src/http/workflow.js +181 -0
- package/dist/src/http/workflow.js.map +1 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/services/cli/invoke.d.ts +5 -0
- package/dist/src/services/cli/invoke.d.ts.map +1 -0
- package/dist/src/services/cli/invoke.js +45 -0
- package/dist/src/services/cli/invoke.js.map +1 -0
- package/dist/src/services/cli/repl-context.d.ts +13 -0
- package/dist/src/services/cli/repl-context.d.ts.map +1 -0
- package/dist/src/services/cli/repl-context.js +60 -0
- package/dist/src/services/cli/repl-context.js.map +1 -0
- package/dist/src/services/cli/repl.d.ts +5 -0
- package/dist/src/services/cli/repl.d.ts.map +1 -0
- package/dist/src/services/cli/repl.js +32 -0
- package/dist/src/services/cli/repl.js.map +1 -0
- package/dist/src/services/cli.d.ts +12 -0
- package/dist/src/services/cli.d.ts.map +1 -0
- package/dist/src/services/cli.js +76 -0
- package/dist/src/services/cli.js.map +1 -0
- package/dist/src/services/index.d.ts +7 -0
- package/dist/src/services/index.d.ts.map +1 -0
- package/dist/src/services/index.js +10 -0
- package/dist/src/services/index.js.map +1 -0
- package/dist/src/services/leader.d.ts +32 -0
- package/dist/src/services/leader.d.ts.map +1 -0
- package/dist/src/services/leader.js +174 -0
- package/dist/src/services/leader.js.map +1 -0
- package/dist/src/services/logger.d.ts +35 -0
- package/dist/src/services/logger.d.ts.map +1 -0
- package/dist/src/services/logger.js +245 -0
- package/dist/src/services/logger.js.map +1 -0
- package/dist/src/services/mail/index.d.ts +61 -0
- package/dist/src/services/mail/index.d.ts.map +1 -0
- package/dist/src/services/mail/index.js +90 -0
- package/dist/src/services/mail/index.js.map +1 -0
- package/dist/src/services/mail/postmark.d.ts +11 -0
- package/dist/src/services/mail/postmark.d.ts.map +1 -0
- package/dist/src/services/mail/postmark.js +42 -0
- package/dist/src/services/mail/postmark.js.map +1 -0
- package/dist/src/services/mail/smtp.d.ts +11 -0
- package/dist/src/services/mail/smtp.d.ts.map +1 -0
- package/dist/src/services/mail/smtp.js +61 -0
- package/dist/src/services/mail/smtp.js.map +1 -0
- package/dist/src/services/mesh.d.ts +65 -0
- package/dist/src/services/mesh.d.ts.map +1 -0
- package/dist/src/services/mesh.js +422 -0
- package/dist/src/services/mesh.js.map +1 -0
- package/dist/src/services/worker/bootstrap.d.ts +3 -0
- package/dist/src/services/worker/bootstrap.d.ts.map +1 -0
- package/dist/src/services/worker/bootstrap.js +64 -0
- package/dist/src/services/worker/bootstrap.js.map +1 -0
- package/dist/src/services/worker/cli.d.ts +11 -0
- package/dist/src/services/worker/cli.d.ts.map +1 -0
- package/dist/src/services/worker/cli.js +43 -0
- package/dist/src/services/worker/cli.js.map +1 -0
- package/dist/src/services/worker/entity.d.ts +18 -0
- package/dist/src/services/worker/entity.d.ts.map +1 -0
- package/dist/src/services/worker/entity.js +16 -0
- package/dist/src/services/worker/entity.js.map +1 -0
- package/dist/src/services/worker/index.d.ts +9 -0
- package/dist/src/services/worker/index.d.ts.map +1 -0
- package/dist/src/services/worker/index.js +40 -0
- package/dist/src/services/worker/index.js.map +1 -0
- package/dist/src/services/worker/queue.d.ts +8 -0
- package/dist/src/services/worker/queue.d.ts.map +1 -0
- package/dist/src/services/worker/queue.js +32 -0
- package/dist/src/services/worker/queue.js.map +1 -0
- package/dist/src/services/worker/recorder.d.ts +16 -0
- package/dist/src/services/worker/recorder.d.ts.map +1 -0
- package/dist/src/services/worker/recorder.js +168 -0
- package/dist/src/services/worker/recorder.js.map +1 -0
- package/dist/src/services/worker/runner.d.ts +21 -0
- package/dist/src/services/worker/runner.d.ts.map +1 -0
- package/dist/src/services/worker/runner.js +156 -0
- package/dist/src/services/worker/runner.js.map +1 -0
- package/dist/src/services/worker/types.d.ts +26 -0
- package/dist/src/services/worker/types.d.ts.map +1 -0
- package/dist/src/services/worker/types.js +29 -0
- package/dist/src/services/worker/types.js.map +1 -0
- package/dist/src/srpc/SrpcByteStream.d.ts +67 -0
- package/dist/src/srpc/SrpcByteStream.d.ts.map +1 -0
- package/dist/src/srpc/SrpcByteStream.js +319 -0
- package/dist/src/srpc/SrpcByteStream.js.map +1 -0
- package/dist/src/srpc/SrpcClient.d.ts +75 -0
- package/dist/src/srpc/SrpcClient.d.ts.map +1 -0
- package/dist/src/srpc/SrpcClient.js +445 -0
- package/dist/src/srpc/SrpcClient.js.map +1 -0
- package/dist/src/srpc/SrpcServer.d.ts +80 -0
- package/dist/src/srpc/SrpcServer.d.ts.map +1 -0
- package/dist/src/srpc/SrpcServer.js +561 -0
- package/dist/src/srpc/SrpcServer.js.map +1 -0
- package/dist/src/srpc/index.d.ts +7 -0
- package/dist/src/srpc/index.d.ts.map +1 -0
- package/dist/src/srpc/index.js +12 -0
- package/dist/src/srpc/index.js.map +1 -0
- package/dist/src/srpc/types.d.ts +131 -0
- package/dist/src/srpc/types.d.ts.map +1 -0
- package/dist/src/srpc/types.js +65 -0
- package/dist/src/srpc/types.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +2 -0
- package/dist/src/telemetry/index.d.ts.map +1 -0
- package/dist/src/telemetry/index.js +5 -0
- package/dist/src/telemetry/index.js.map +1 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.d.ts +22 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.d.ts.map +1 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.js +248 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.js.map +1 -0
- package/dist/src/telemetry/otel/helpers.d.ts +27 -0
- package/dist/src/telemetry/otel/helpers.d.ts.map +1 -0
- package/dist/src/telemetry/otel/helpers.js +126 -0
- package/dist/src/telemetry/otel/helpers.js.map +1 -0
- package/dist/src/telemetry/otel/index.d.ts +14 -0
- package/dist/src/telemetry/otel/index.d.ts.map +1 -0
- package/dist/src/telemetry/otel/index.js +132 -0
- package/dist/src/telemetry/otel/index.js.map +1 -0
- package/dist/src/telemetry/otel/metrics.controller.d.ts +6 -0
- package/dist/src/telemetry/otel/metrics.controller.d.ts.map +1 -0
- package/dist/src/telemetry/otel/metrics.controller.js +63 -0
- package/dist/src/telemetry/otel/metrics.controller.js.map +1 -0
- package/dist/src/telemetry/sentry.d.ts +9 -0
- package/dist/src/telemetry/sentry.d.ts.map +1 -0
- package/dist/src/telemetry/sentry.js +62 -0
- package/dist/src/telemetry/sentry.js.map +1 -0
- package/dist/src/testing/expect.d.ts +25 -0
- package/dist/src/testing/expect.d.ts.map +1 -0
- package/dist/src/testing/expect.js +151 -0
- package/dist/src/testing/expect.js.map +1 -0
- package/dist/src/testing/fixtures.d.ts +19 -0
- package/dist/src/testing/fixtures.d.ts.map +1 -0
- package/dist/src/testing/fixtures.js +69 -0
- package/dist/src/testing/fixtures.js.map +1 -0
- package/dist/src/testing/index.d.ts +260 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +345 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/testing/requests.d.ts +10 -0
- package/dist/src/testing/requests.d.ts.map +1 -0
- package/dist/src/testing/requests.js +56 -0
- package/dist/src/testing/requests.js.map +1 -0
- package/dist/src/testing/sql.d.ts +11 -0
- package/dist/src/testing/sql.d.ts.map +1 -0
- package/dist/src/testing/sql.js +55 -0
- package/dist/src/testing/sql.js.map +1 -0
- package/dist/src/types/index.d.ts +57 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +73 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/phone.d.ts +11 -0
- package/dist/src/types/phone.d.ts.map +1 -0
- package/dist/src/types/phone.js +73 -0
- package/dist/src/types/phone.js.map +1 -0
- package/docs/.vitepress/config.mts +79 -0
- package/docs/.yarnrc.yml +1 -0
- package/docs/content/CONTRIBUTING.md +140 -0
- package/docs/content/README-DEV.md +142 -0
- package/docs/content/README.md +39 -0
- package/docs/content/authentication.md +215 -0
- package/docs/content/cli.md +335 -0
- package/docs/content/configuration.md +175 -0
- package/docs/content/database.md +422 -0
- package/docs/content/devconsole.md +123 -0
- package/docs/content/getting-started.md +154 -0
- package/docs/content/guides/test-migration-guide.md +351 -0
- package/docs/content/health.md +54 -0
- package/docs/content/helpers.md +322 -0
- package/docs/content/http.md +253 -0
- package/docs/content/index.md +147 -0
- package/docs/content/leader-service.md +98 -0
- package/docs/content/logging.md +150 -0
- package/docs/content/mail.md +161 -0
- package/docs/content/mesh-service.md +204 -0
- package/docs/content/public/images/devconsole/01-dashboard.png +0 -0
- package/docs/content/public/images/devconsole/02-routes.png +0 -0
- package/docs/content/public/images/devconsole/03-openapi.png +0 -0
- package/docs/content/public/images/devconsole/04-requests.png +0 -0
- package/docs/content/public/images/devconsole/05-srpc.png +0 -0
- package/docs/content/public/images/devconsole/06-database.png +0 -0
- package/docs/content/public/images/devconsole/07-health.png +0 -0
- package/docs/content/public/images/devconsole/08-mutex.png +0 -0
- package/docs/content/public/images/devconsole/09-repl.png +0 -0
- package/docs/content/public/images/devconsole/10-workers.png +0 -0
- package/docs/content/redis.md +168 -0
- package/docs/content/srpc.md +261 -0
- package/docs/content/telemetry.md +166 -0
- package/docs/content/testing.md +222 -0
- package/docs/content/types.md +215 -0
- package/docs/content/worker.md +177 -0
- package/docs/package.json +16 -0
- package/docs/scripts/README-SCREENSHOTS.md +145 -0
- package/docs/scripts/capture-devconsole-screenshots.js +184 -0
- package/docs/yarn.lock +2408 -0
- package/package.json +144 -0
- package/patches/@deepkit+type+1.0.19.patch +38 -0
- package/patches/deepkit-openapi-core+0.0.9.patch +62 -0
- package/src/app/base.ts +253 -0
- package/src/app/config.loader.ts +66 -0
- package/src/app/config.ts +119 -0
- package/src/app/const.ts +4 -0
- package/src/app/dev.ts +92 -0
- package/src/app/index.ts +6 -0
- package/src/app/openapi.ts +3 -0
- package/src/app/resolver.ts +49 -0
- package/src/app/shutdown.ts +55 -0
- package/src/app/state.ts +19 -0
- package/src/auth/index.ts +2 -0
- package/src/auth/jwt.ts +275 -0
- package/src/auth/provider.ts +57 -0
- package/src/cli/dksf-dev.ts +416 -0
- package/src/cli/dksf-gen-proto.ts +176 -0
- package/src/cli/dksf-install.ts +11 -0
- package/src/cli/dksf-test.ts +84 -0
- package/src/cli/dksf-update.ts +101 -0
- package/src/database/common.ts +385 -0
- package/src/database/dialect.ts +43 -0
- package/src/database/entity.ts +285 -0
- package/src/database/index.ts +7 -0
- package/src/database/migration/MigrationResetCommand.ts +72 -0
- package/src/database/migration/MigrationRunCommand.ts +118 -0
- package/src/database/migration/characters.ts +53 -0
- package/src/database/migration/create/MigrationCreateCommand.ts +96 -0
- package/src/database/migration/create/comparator.ts +467 -0
- package/src/database/migration/create/db-reader.ts +510 -0
- package/src/database/migration/create/ddl-generator.ts +755 -0
- package/src/database/migration/create/entity-reader.ts +471 -0
- package/src/database/migration/create/file-generator.ts +57 -0
- package/src/database/migration/create/prompt.ts +49 -0
- package/src/database/migration/create/schema-model.ts +102 -0
- package/src/database/migration/helpers.ts +7 -0
- package/src/database/migration/index.ts +35 -0
- package/src/database/migration/migration.entity.ts +10 -0
- package/src/database/mysql.ts +140 -0
- package/src/database/postgres.ts +97 -0
- package/src/database/types.ts +18 -0
- package/src/devconsole/devconsole.controller.ts +59 -0
- package/src/devconsole/devconsole.middleware.ts +23 -0
- package/src/devconsole/devconsole.srpc.ts +94 -0
- package/src/devconsole/devconsole.store.ts +190 -0
- package/src/devconsole/devconsole.ws.ts +491 -0
- package/src/devconsole/index.ts +1 -0
- package/src/devconsole/patches.ts +428 -0
- package/src/health/health.module.ts +30 -0
- package/src/health/healthcheck.controller.ts +17 -0
- package/src/health/healthcheck.service.ts +28 -0
- package/src/health/index.ts +2 -0
- package/src/helpers/async/context.ts +67 -0
- package/src/helpers/async/process.ts +49 -0
- package/src/helpers/async/promise.ts +16 -0
- package/src/helpers/data/array.ts +11 -0
- package/src/helpers/data/objects.ts +64 -0
- package/src/helpers/data/serialization.ts +11 -0
- package/src/helpers/data/transformer.ts +54 -0
- package/src/helpers/framework/decorators.ts +27 -0
- package/src/helpers/framework/event.ts +11 -0
- package/src/helpers/framework/injection.ts +47 -0
- package/src/helpers/index.ts +34 -0
- package/src/helpers/io/package.ts +26 -0
- package/src/helpers/io/stream.ts +79 -0
- package/src/helpers/redis/broadcast.ts +96 -0
- package/src/helpers/redis/cache.ts +28 -0
- package/src/helpers/redis/mutex.ts +260 -0
- package/src/helpers/redis/redis.ts +60 -0
- package/src/helpers/security/crypto.ts +133 -0
- package/src/helpers/security/validation.ts +16 -0
- package/src/helpers/utils/date.ts +13 -0
- package/src/helpers/utils/error.ts +155 -0
- package/src/helpers/utils/jsx.ts +8 -0
- package/src/helpers/utils/uuid.ts +8 -0
- package/src/http/auth.ts +156 -0
- package/src/http/context.ts +15 -0
- package/src/http/cors.ts +159 -0
- package/src/http/errors.ts +9 -0
- package/src/http/index.ts +19 -0
- package/src/http/kernel.ts +138 -0
- package/src/http/middleware.ts +59 -0
- package/src/http/overrides.ts +20 -0
- package/src/http/store.ts +86 -0
- package/src/http/uploads.ts +6 -0
- package/src/http/workflow.ts +167 -0
- package/src/index.ts +19 -0
- package/src/services/cli/invoke.ts +39 -0
- package/src/services/cli/repl-context.ts +63 -0
- package/src/services/cli/repl.ts +22 -0
- package/src/services/cli.ts +74 -0
- package/src/services/index.ts +6 -0
- package/src/services/leader.ts +201 -0
- package/src/services/logger.ts +258 -0
- package/src/services/mail/index.ts +117 -0
- package/src/services/mail/postmark.ts +37 -0
- package/src/services/mail/smtp.ts +46 -0
- package/src/services/mesh.ts +508 -0
- package/src/services/worker/bootstrap.ts +53 -0
- package/src/services/worker/cli.ts +32 -0
- package/src/services/worker/entity.ts +22 -0
- package/src/services/worker/index.ts +30 -0
- package/src/services/worker/queue.ts +35 -0
- package/src/services/worker/recorder.ts +172 -0
- package/src/services/worker/runner.ts +179 -0
- package/src/services/worker/types.ts +32 -0
- package/src/srpc/SrpcByteStream.ts +382 -0
- package/src/srpc/SrpcClient.ts +512 -0
- package/src/srpc/SrpcServer.ts +681 -0
- package/src/srpc/index.ts +15 -0
- package/src/srpc/types.ts +146 -0
- package/src/telemetry/index.ts +1 -0
- package/src/telemetry/otel/MariaDBInstrumentation.ts +297 -0
- package/src/telemetry/otel/helpers.ts +117 -0
- package/src/telemetry/otel/index.ts +150 -0
- package/src/telemetry/otel/metrics.controller.ts +50 -0
- package/src/telemetry/sentry.ts +58 -0
- package/src/testing/expect.ts +148 -0
- package/src/testing/fixtures.ts +62 -0
- package/src/testing/index.ts +355 -0
- package/src/testing/requests.ts +68 -0
- package/src/testing/sql.ts +50 -0
- package/src/types/index.ts +64 -0
- package/src/types/phone.ts +64 -0
- package/types.d.ts +20 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# MeshService
|
|
2
|
+
|
|
3
|
+
Typed RPC between distributed application instances. Each node gets a unique integer ID and can invoke handlers on any other node (or itself) with full type safety. Uses Redis pub/sub for messaging and sorted sets for node tracking.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
### Define a message map
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { MeshService, MeshMessageMap } from '@zyno-io/dk-server-foundation';
|
|
11
|
+
|
|
12
|
+
type MyMessages = {
|
|
13
|
+
getStatus: { request: { verbose: boolean }; response: { status: string; uptime: number } };
|
|
14
|
+
invalidateCache: { request: { keys: string[] }; response: { cleared: number } };
|
|
15
|
+
};
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Create and start a node
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
const mesh = new MeshService<MyMessages>('my-app');
|
|
22
|
+
|
|
23
|
+
mesh.registerHandler('getStatus', async data => {
|
|
24
|
+
return { status: 'ok', uptime: process.uptime() };
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
mesh.registerHandler('invalidateCache', async data => {
|
|
28
|
+
const cleared = await cache.delete(data.keys);
|
|
29
|
+
return { cleared };
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
await mesh.start();
|
|
33
|
+
console.log(`Node started with instance ID: ${mesh.instanceId}`);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Invoke a handler on another node
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// Call a specific node by its instance ID
|
|
40
|
+
const result = await mesh.invoke(targetInstanceId, 'getStatus', { verbose: true });
|
|
41
|
+
console.log(result.status); // fully typed
|
|
42
|
+
|
|
43
|
+
// Calling your own instance ID routes directly to the local handler (no pub/sub)
|
|
44
|
+
const local = await mesh.invoke(mesh.instanceId, 'getStatus', { verbose: false });
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### List nodes in the mesh
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
const nodes = await mesh.getNodes();
|
|
51
|
+
for (const node of nodes) {
|
|
52
|
+
console.log(`${node.instanceId} @ ${node.hostname}${node.self ? ' (self)' : ''}`);
|
|
53
|
+
}
|
|
54
|
+
// 1 @ web-server-01
|
|
55
|
+
// 2 @ web-server-02 (self)
|
|
56
|
+
// 3 @ web-server-03
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Track node departures
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
mesh.setNodeCleanedUpCallback(async instanceId => {
|
|
63
|
+
console.log(`Node ${instanceId} left the mesh`);
|
|
64
|
+
// Clean up resources associated with that node
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Graceful shutdown
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
await mesh.stop();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## API
|
|
75
|
+
|
|
76
|
+
### `new MeshService<T extends MeshMessageMap>(key: string, options?: MeshServiceOptions)`
|
|
77
|
+
|
|
78
|
+
Creates a new mesh node.
|
|
79
|
+
|
|
80
|
+
- **`key`** -- Logical mesh name. All nodes using the same key form one mesh. Different keys are fully independent.
|
|
81
|
+
- **`options`** -- Optional tuning parameters (see below).
|
|
82
|
+
|
|
83
|
+
### `MeshServiceOptions`
|
|
84
|
+
|
|
85
|
+
| Option | Type | Default | Description |
|
|
86
|
+
| --------------------- | ---------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
87
|
+
| `heartbeatIntervalMs` | `number` | `5000` | How often this node refreshes its heartbeat in the registry. |
|
|
88
|
+
| `nodeTtlMs` | `number` | `15000` | How long a node can go without a heartbeat before the leader removes it. |
|
|
89
|
+
| `requestTimeoutMs` | `number` | `10000` | Default timeout for remote invocations. Reset on each heartbeat from the handler, so long-running handlers won't time out. |
|
|
90
|
+
| `leaderOptions` | `LeaderServiceOptions` | — | Options passed to the internal `LeaderService` used for cleanup leader election. |
|
|
91
|
+
|
|
92
|
+
### Properties
|
|
93
|
+
|
|
94
|
+
| Property | Type | Description |
|
|
95
|
+
| ------------ | -------- | ----------------------------------------------------------------------- |
|
|
96
|
+
| `instanceId` | `number` | Unique integer ID assigned to this node on `start()`. `0` before start. |
|
|
97
|
+
|
|
98
|
+
### Methods
|
|
99
|
+
|
|
100
|
+
#### `registerHandler<K>(type: K, handler: (data: T[K]['request']) => T[K]['response'] | Promise<T[K]['response']>): void`
|
|
101
|
+
|
|
102
|
+
Register a handler for a message type. Handlers can be registered before or after `start()`. Registering a handler for a type that already has one replaces it.
|
|
103
|
+
|
|
104
|
+
#### `invoke<K>(instanceId: number, type: K, data: T[K]['request']): Promise<T[K]['response']>`
|
|
105
|
+
|
|
106
|
+
Send a typed request to a specific node and wait for the response.
|
|
107
|
+
|
|
108
|
+
- If `instanceId` matches the local node, the handler is called directly (no pub/sub).
|
|
109
|
+
- If the target node doesn't exist or doesn't respond, the promise rejects with `MeshRequestTimeoutError`.
|
|
110
|
+
- If the target has no handler for the type, rejects with `MeshNoHandlerError`.
|
|
111
|
+
- If the handler throws, rejects with `MeshHandlerError` containing the error message.
|
|
112
|
+
|
|
113
|
+
#### `getNodes(): Promise<MeshNode[]>`
|
|
114
|
+
|
|
115
|
+
Returns all live nodes in the mesh. Each `MeshNode` contains:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
interface MeshNode {
|
|
119
|
+
instanceId: number; // The node's unique integer ID
|
|
120
|
+
hostname: string; // The OS hostname of the machine running the node
|
|
121
|
+
self: boolean; // true if this is the calling node
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Only nodes with active heartbeats are returned. Stopped or expired nodes are excluded.
|
|
126
|
+
|
|
127
|
+
#### `setNodeCleanedUpCallback(cb: (instanceId: number) => void | Promise<void>): void`
|
|
128
|
+
|
|
129
|
+
Register a callback invoked when the leader detects and removes an expired node. Only fires on the current leader instance. Errors in the callback are logged but don't affect cleanup of other nodes.
|
|
130
|
+
|
|
131
|
+
#### `start(): Promise<void>`
|
|
132
|
+
|
|
133
|
+
Join the mesh. Acquires a unique instance ID, subscribes to its pub/sub channel, registers in the heartbeat set, and starts leader election. Throws if already running.
|
|
134
|
+
|
|
135
|
+
#### `stop(): Promise<void>`
|
|
136
|
+
|
|
137
|
+
Leave the mesh. Stops heartbeats, rejects all pending outbound requests with `Error('MeshService stopped')`, unsubscribes from pub/sub, and removes itself from the heartbeat registry. Safe to call before `start()` or multiple times.
|
|
138
|
+
|
|
139
|
+
## Error Classes
|
|
140
|
+
|
|
141
|
+
### `MeshRequestTimeoutError`
|
|
142
|
+
|
|
143
|
+
The target node did not respond within the timeout period. This can happen if the target has crashed, is unreachable, or the Redis pub/sub connection is disrupted.
|
|
144
|
+
|
|
145
|
+
### `MeshHandlerError`
|
|
146
|
+
|
|
147
|
+
The target node's handler threw an error. The `message` property contains the original error message from the remote handler.
|
|
148
|
+
|
|
149
|
+
### `MeshNoHandlerError`
|
|
150
|
+
|
|
151
|
+
No handler is registered for the requested message type -- either locally (direct invocation) or on the remote node.
|
|
152
|
+
|
|
153
|
+
## Architecture
|
|
154
|
+
|
|
155
|
+
### Node Registry
|
|
156
|
+
|
|
157
|
+
Nodes are tracked in a Redis sorted set (`{prefix}:mesh:{key}:heartbeats`) where the score is the last heartbeat timestamp (from Redis server time, avoiding clock skew) and the member is the instance ID. Node metadata (hostname) is stored in a Redis hash (`{prefix}:mesh:{key}:nodes`).
|
|
158
|
+
|
|
159
|
+
Unique instance IDs are assigned via `INCR` on `{prefix}:mesh:{key}:next_id`. Both the heartbeat entry and the nodes hash entry are removed on graceful stop or leader-driven cleanup of expired nodes.
|
|
160
|
+
|
|
161
|
+
### Messaging
|
|
162
|
+
|
|
163
|
+
Each node subscribes to its own pub/sub channel: `{prefix}:mesh:{key}:node:{instanceId}`.
|
|
164
|
+
|
|
165
|
+
Three message types flow over these channels:
|
|
166
|
+
|
|
167
|
+
| Type | Direction | Purpose |
|
|
168
|
+
| ------------- | ----------------- | -------------------------------------------------------- |
|
|
169
|
+
| **Request** | Caller -> Handler | `{ requestId, senderInstanceId, type, data, timeoutMs }` |
|
|
170
|
+
| **Response** | Handler -> Caller | `{ requestId, reply: true, data?, error? }` |
|
|
171
|
+
| **Heartbeat** | Handler -> Caller | `{ requestId, heartbeat: true }` |
|
|
172
|
+
|
|
173
|
+
### Request Heartbeats
|
|
174
|
+
|
|
175
|
+
While a handler is executing, the handling node sends periodic heartbeat messages back to the caller (every `requestTimeoutMs * 0.75`). The caller resets its timeout timer on each heartbeat. This allows short absolute timeouts while supporting arbitrarily long handler execution.
|
|
176
|
+
|
|
177
|
+
The handler uses the **caller's** `requestTimeoutMs` (sent in the request message) for its heartbeat interval, so mixed-timeout configurations work correctly.
|
|
178
|
+
|
|
179
|
+
### Leader Election
|
|
180
|
+
|
|
181
|
+
Each mesh uses an internal `LeaderService` (key: `mesh:{key}`) for leader election. The leader is responsible for:
|
|
182
|
+
|
|
183
|
+
1. Running the cleanup Lua script on each heartbeat cycle
|
|
184
|
+
2. Removing expired nodes from the sorted set
|
|
185
|
+
3. Invoking the `nodeCleanedUpCallback` for each removed node
|
|
186
|
+
|
|
187
|
+
Only one node (the leader) performs cleanup at any time.
|
|
188
|
+
|
|
189
|
+
### Local Invocation
|
|
190
|
+
|
|
191
|
+
When `invoke` is called with the node's own instance ID, the handler is called directly as a function call -- no serialization, no pub/sub, no timeout. Errors propagate as-is.
|
|
192
|
+
|
|
193
|
+
## Configuration
|
|
194
|
+
|
|
195
|
+
The Redis connection is configured via environment variables with the `MESH_REDIS_` prefix (falls back to `REDIS_`):
|
|
196
|
+
|
|
197
|
+
| Variable | Description |
|
|
198
|
+
| -------------------------- | ------------------------------------------------------------ |
|
|
199
|
+
| `MESH_REDIS_HOST` | Redis host |
|
|
200
|
+
| `MESH_REDIS_PORT` | Redis port |
|
|
201
|
+
| `MESH_REDIS_PREFIX` | Key prefix (falls back to `REDIS_PREFIX`, then package name) |
|
|
202
|
+
| `MESH_REDIS_SENTINEL_HOST` | Sentinel host (optional) |
|
|
203
|
+
| `MESH_REDIS_SENTINEL_PORT` | Sentinel port (optional) |
|
|
204
|
+
| `MESH_REDIS_SENTINEL_NAME` | Sentinel master name (optional) |
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Redis
|
|
2
|
+
|
|
3
|
+
Utilities for Redis-backed caching, distributed locking, and inter-process communication.
|
|
4
|
+
|
|
5
|
+
## Client Creation
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { createRedis, createRedisOptions } from '@zyno-io/dk-server-foundation';
|
|
9
|
+
|
|
10
|
+
// Create with default config (REDIS_HOST, REDIS_PORT)
|
|
11
|
+
const { client, prefix } = createRedis();
|
|
12
|
+
|
|
13
|
+
// Create with specific config prefix
|
|
14
|
+
const { client, prefix } = createRedis('CACHE_REDIS');
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Each call creates a separate connection. All clients are tracked and can be disconnected with `disconnectAllRedis()`.
|
|
18
|
+
|
|
19
|
+
## Cache
|
|
20
|
+
|
|
21
|
+
Redis-backed cache with TTL support:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { Cache } from '@zyno-io/dk-server-foundation';
|
|
25
|
+
|
|
26
|
+
// String values
|
|
27
|
+
await Cache.set('key', 'value', 3600); // TTL in seconds
|
|
28
|
+
const value = await Cache.get('key');
|
|
29
|
+
|
|
30
|
+
// Object values (auto JSON serialization)
|
|
31
|
+
await Cache.setObj('user:123', { name: 'Alice', role: 'admin' }, 3600);
|
|
32
|
+
const user = await Cache.getObj<{ name: string; role: string }>('user:123');
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| Method | Description |
|
|
36
|
+
| ----------------------------- | ---------------------------------------------- |
|
|
37
|
+
| `Cache.get(key)` | Get a string value (returns `null` if missing) |
|
|
38
|
+
| `Cache.set(key, val, ttl)` | Set a string value with TTL in seconds |
|
|
39
|
+
| `Cache.getObj<T>(key)` | Get and deserialize a JSON value |
|
|
40
|
+
| `Cache.setObj(key, val, ttl)` | Serialize and set a JSON value with TTL |
|
|
41
|
+
|
|
42
|
+
Uses `CACHE_REDIS_*` environment variables (falls back to `REDIS_*`).
|
|
43
|
+
|
|
44
|
+
## Distributed Mutex
|
|
45
|
+
|
|
46
|
+
Redis-backed distributed locking for coordinating work across multiple instances:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { withMutex, withMutexes, MutexAcquisitionError } from '@zyno-io/dk-server-foundation';
|
|
50
|
+
|
|
51
|
+
// Single mutex
|
|
52
|
+
const result = await withMutex({
|
|
53
|
+
key: ['user', userId],
|
|
54
|
+
fn: async didWait => {
|
|
55
|
+
// Critical section - only one instance executes at a time
|
|
56
|
+
// didWait: true if we had to wait for the lock
|
|
57
|
+
return await processPayment(userId);
|
|
58
|
+
},
|
|
59
|
+
retryCount: 30, // Max retry attempts (default: 30)
|
|
60
|
+
retryDelay: 1000, // Delay between retries in ms (default: 1000)
|
|
61
|
+
renewInterval: 1000 // Lock renewal interval in ms (default: 1000)
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Multiple mutexes (acquired in order)
|
|
65
|
+
const result = await withMutexes({
|
|
66
|
+
keys: [
|
|
67
|
+
['wallet', walletA],
|
|
68
|
+
['wallet', walletB]
|
|
69
|
+
],
|
|
70
|
+
fn: async didWait => {
|
|
71
|
+
return await transferFunds(walletA, walletB, amount);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Keys
|
|
77
|
+
|
|
78
|
+
Mutex keys can be primitives or arrays: `['wallet', 123]` becomes `wallet:123`.
|
|
79
|
+
|
|
80
|
+
### Error Handling
|
|
81
|
+
|
|
82
|
+
Throws `MutexAcquisitionError` if the lock cannot be acquired within the retry window.
|
|
83
|
+
|
|
84
|
+
### Options
|
|
85
|
+
|
|
86
|
+
| Option | Type | Default | Description |
|
|
87
|
+
| --------------- | ---------------------------------- | ------- | -------------------------------------- |
|
|
88
|
+
| `key` / `keys` | `MutexKey` | — | Lock key(s) — string, number, or array |
|
|
89
|
+
| `fn` | `(didWait: boolean) => Promise<T>` | — | Function to execute under lock |
|
|
90
|
+
| `retryCount` | `number` | `30` | Max retry attempts |
|
|
91
|
+
| `retryDelay` | `number` | `1000` | Delay between retries (ms) |
|
|
92
|
+
| `renewInterval` | `number` | `1000` | Lock renewal interval (ms) |
|
|
93
|
+
|
|
94
|
+
### Modes
|
|
95
|
+
|
|
96
|
+
Configure via `MUTEX_MODE`:
|
|
97
|
+
|
|
98
|
+
- **`redis`** (default) — Uses Redis Lua scripts for atomic acquire/release/renew. Suitable for multi-instance deployments.
|
|
99
|
+
- **`local`** — In-process locking with no Redis dependency. Useful for single-instance or testing scenarios.
|
|
100
|
+
|
|
101
|
+
Uses `MUTEX_REDIS_*` environment variables (falls back to `REDIS_*`).
|
|
102
|
+
|
|
103
|
+
### DevConsole Integration
|
|
104
|
+
|
|
105
|
+
Active mutexes and acquisition history are visible in the [DevConsole](./devconsole.md) Mutex view.
|
|
106
|
+
|
|
107
|
+
## Broadcast Channels
|
|
108
|
+
|
|
109
|
+
Redis pub/sub for inter-process communication:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { createBroadcastChannel } from '@zyno-io/dk-server-foundation';
|
|
113
|
+
|
|
114
|
+
// Create a typed broadcast channel
|
|
115
|
+
const channel = createBroadcastChannel<{ userId: string; action: string }>('user-events');
|
|
116
|
+
|
|
117
|
+
channel.subscribe(data => {
|
|
118
|
+
console.log(`${data.userId}: ${data.action}`);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
channel.publish({ userId: '123', action: 'login' });
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Distributed Methods
|
|
125
|
+
|
|
126
|
+
Execute a function locally and broadcast to all instances:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { createDistributedMethod } from '@zyno-io/dk-server-foundation';
|
|
130
|
+
|
|
131
|
+
class CacheManager {
|
|
132
|
+
invalidate = createDistributedMethod<{ key: string }>(
|
|
133
|
+
{
|
|
134
|
+
name: 'invalidate',
|
|
135
|
+
logger: () => this.logger
|
|
136
|
+
},
|
|
137
|
+
async data => {
|
|
138
|
+
this.localCache.delete(data.key);
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Calling invalidate() runs locally AND broadcasts to all instances
|
|
144
|
+
await cacheManager.invalidate({ key: 'user:123' });
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The `logger` option takes a getter function so it can reference `this.logger` even when used as a class field initializer. If omitted, a default logger scoped to `Distributed:<name>` is used.
|
|
148
|
+
|
|
149
|
+
Uses `BROADCAST_REDIS_*` environment variables (falls back to `REDIS_*`).
|
|
150
|
+
|
|
151
|
+
## Configuration
|
|
152
|
+
|
|
153
|
+
All Redis utilities support independent connection configuration via environment variable prefixes:
|
|
154
|
+
|
|
155
|
+
| Utility | Env Prefix | Fallback |
|
|
156
|
+
| --------- | ------------------- | --------- |
|
|
157
|
+
| Cache | `CACHE_REDIS_*` | `REDIS_*` |
|
|
158
|
+
| Mutex | `MUTEX_REDIS_*` | `REDIS_*` |
|
|
159
|
+
| Broadcast | `BROADCAST_REDIS_*` | `REDIS_*` |
|
|
160
|
+
|
|
161
|
+
Common variables for each prefix:
|
|
162
|
+
|
|
163
|
+
| Variable | Description | Default |
|
|
164
|
+
| -------------- | -------------- | ----------- |
|
|
165
|
+
| `*_HOST` | Redis host | `127.0.0.1` |
|
|
166
|
+
| `*_PORT` | Redis port | `6379` |
|
|
167
|
+
| `*_DB` | Redis database | `0` |
|
|
168
|
+
| `*_KEY_PREFIX` | Key prefix | — |
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# SRPC (Simple RPC)
|
|
2
|
+
|
|
3
|
+
Bidirectional RPC over WebSocket with HMAC authentication, ts-proto code generation, multiplexed binary streams, and OpenTelemetry tracing.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
SRPC uses a prefix-based message routing system. Messages are defined in `.proto` files and compiled to TypeScript with `dksf-gen-proto`. Prefixes determine direction:
|
|
8
|
+
|
|
9
|
+
- `u*` -- Upstream: client -> server requests
|
|
10
|
+
- `d*` -- Downstream: server -> client requests
|
|
11
|
+
|
|
12
|
+
## Proto Generation
|
|
13
|
+
|
|
14
|
+
Define messages in a `.proto` file:
|
|
15
|
+
|
|
16
|
+
```protobuf
|
|
17
|
+
syntax = "proto3";
|
|
18
|
+
|
|
19
|
+
message ClientMessage {
|
|
20
|
+
string requestId = 1;
|
|
21
|
+
bytes reply = 2;
|
|
22
|
+
string error = 3;
|
|
23
|
+
bytes trace = 4;
|
|
24
|
+
bytes pingPong = 5;
|
|
25
|
+
bytes byteStreamOperation = 6;
|
|
26
|
+
|
|
27
|
+
// Upstream (client -> server)
|
|
28
|
+
bytes uEcho = 100;
|
|
29
|
+
bytes uGetUser = 101;
|
|
30
|
+
|
|
31
|
+
// Downstream (server -> client)
|
|
32
|
+
bytes dNotify = 200;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
message ServerMessage {
|
|
36
|
+
string requestId = 1;
|
|
37
|
+
bytes reply = 2;
|
|
38
|
+
string error = 3;
|
|
39
|
+
bytes trace = 4;
|
|
40
|
+
bytes pingPong = 5;
|
|
41
|
+
bytes byteStreamOperation = 6;
|
|
42
|
+
|
|
43
|
+
bytes uEcho = 100;
|
|
44
|
+
bytes uGetUser = 101;
|
|
45
|
+
bytes dNotify = 200;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Request/response types
|
|
49
|
+
message UEchoRequest { string message = 1; }
|
|
50
|
+
message UEchoResponse { string message = 1; }
|
|
51
|
+
message UGetUserRequest { int32 id = 1; }
|
|
52
|
+
message UGetUserResponse { string name = 1; string email = 2; }
|
|
53
|
+
message DNotifyRequest { string event = 1; }
|
|
54
|
+
message DNotifyResponse { bool acknowledged = 1; }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Generate TypeScript:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
dksf-gen-proto my-service.proto src/generated/proto/my-service
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Options:
|
|
64
|
+
|
|
65
|
+
| Flag | Description |
|
|
66
|
+
| ---------------- | ---------------------------------- |
|
|
67
|
+
| `--use-date` | Use `Date` instead of `Timestamp` |
|
|
68
|
+
| `--use-map-type` | Use `Map` instead of plain objects |
|
|
69
|
+
| `--only-types` | Generate only type definitions |
|
|
70
|
+
|
|
71
|
+
## Server
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { SrpcServer } from '@zyno-io/dk-server-foundation';
|
|
75
|
+
import { ClientMessage, ServerMessage } from './generated/proto/my-service';
|
|
76
|
+
|
|
77
|
+
const server = new SrpcServer({
|
|
78
|
+
logger: myLogger,
|
|
79
|
+
clientMessage: ClientMessage,
|
|
80
|
+
serverMessage: ServerMessage,
|
|
81
|
+
wsPath: '/rpc'
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Handle new connections
|
|
85
|
+
server.registerConnectionHandler(async stream => {
|
|
86
|
+
console.log(`Client connected: ${stream.clientId}`);
|
|
87
|
+
stream.meta = { userId: stream.clientId };
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Handle upstream messages (client -> server)
|
|
91
|
+
server.registerMessageHandler('uEcho', async (stream, data) => {
|
|
92
|
+
return { message: data.message };
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
server.registerMessageHandler('uGetUser', async (stream, data) => {
|
|
96
|
+
const user = await db.query(User).filter({ id: data.id }).findOne();
|
|
97
|
+
return { name: user.name, email: user.email };
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Handle disconnections
|
|
101
|
+
server.registerDisconnectHandler(async (stream, cause) => {
|
|
102
|
+
console.log(`Client ${stream.clientId} disconnected: ${cause}`);
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Invoking Client Methods (Server -> Client)
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Send to a specific client
|
|
110
|
+
const stream = server.streamsById.get(streamId);
|
|
111
|
+
const result = await server.invoke(stream, 'dNotify', { event: 'orderUpdated' });
|
|
112
|
+
|
|
113
|
+
// Create a reusable invoke function
|
|
114
|
+
const invoke = SrpcServer.createInvoke(() => server);
|
|
115
|
+
await invoke(stream, 'dNotify', { event: 'orderUpdated' }, 5000);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `ISrpcServerOptions`
|
|
119
|
+
|
|
120
|
+
| Option | Type | Description |
|
|
121
|
+
| --------------- | ---------------- | -------------------------------------- |
|
|
122
|
+
| `logger` | `ScopedLogger` | Logger instance |
|
|
123
|
+
| `clientMessage` | `SrpcMessageFns` | ts-proto generated client message type |
|
|
124
|
+
| `serverMessage` | `SrpcMessageFns` | ts-proto generated server message type |
|
|
125
|
+
| `wsPath` | `string` | WebSocket path (e.g., `/rpc`) |
|
|
126
|
+
| `debug` | `boolean` | Enable debug logging |
|
|
127
|
+
|
|
128
|
+
### Server Properties
|
|
129
|
+
|
|
130
|
+
| Property | Type | Description |
|
|
131
|
+
| ------------------- | ------------------------- | ------------------------------- |
|
|
132
|
+
| `streamsById` | `Map<string, SrpcStream>` | All active streams by stream ID |
|
|
133
|
+
| `streamsByClientId` | `Map<string, SrpcStream>` | Active streams by client ID |
|
|
134
|
+
|
|
135
|
+
### Authentication
|
|
136
|
+
|
|
137
|
+
Default authentication uses HMAC signatures with clock drift tolerance:
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// Override authorization logic
|
|
141
|
+
server.setClientAuthorizer(async (clientId, signature, timestamp) => {
|
|
142
|
+
// Custom auth logic
|
|
143
|
+
return isValid;
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Provide per-client secrets
|
|
147
|
+
server.setClientKeyFetcher(async clientId => {
|
|
148
|
+
return await getClientSecret(clientId);
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Configure via `SRPC_AUTH_SECRET` and `SRPC_AUTH_CLOCK_DRIFT_MS` (default: 30 seconds).
|
|
153
|
+
|
|
154
|
+
## Client
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { SrpcClient } from '@zyno-io/dk-server-foundation';
|
|
158
|
+
import { ClientMessage, ServerMessage } from './generated/proto/my-service';
|
|
159
|
+
|
|
160
|
+
const client = new SrpcClient(
|
|
161
|
+
logger,
|
|
162
|
+
'wss://api.example.com/rpc',
|
|
163
|
+
ClientMessage,
|
|
164
|
+
ServerMessage,
|
|
165
|
+
'client-id-123',
|
|
166
|
+
{ role: 'worker' }, // Optional metadata
|
|
167
|
+
'shared-secret', // Optional auth secret
|
|
168
|
+
{ enableReconnect: true } // Options
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
client.connect(); // Non-async: initiates connection in background
|
|
172
|
+
|
|
173
|
+
// Handle downstream messages (server -> client)
|
|
174
|
+
client.registerMessageHandler('dNotify', async data => {
|
|
175
|
+
console.log(`Event: ${data.event}`);
|
|
176
|
+
return { acknowledged: true };
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Invoke upstream messages (client -> server)
|
|
180
|
+
const result = await client.invoke('uEcho', { message: 'hello' });
|
|
181
|
+
console.log(result.message); // 'hello'
|
|
182
|
+
|
|
183
|
+
// Connection lifecycle
|
|
184
|
+
client.registerConnectionHandler(async () => {
|
|
185
|
+
/* connected */
|
|
186
|
+
});
|
|
187
|
+
client.registerDisconnectHandler(async cause => {
|
|
188
|
+
/* disconnected */
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Check connection status
|
|
192
|
+
if (client.isConnected) {
|
|
193
|
+
/* ... */
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Disconnect (non-async: closes connection immediately)
|
|
197
|
+
client.disconnect();
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### `SrpcClientOptions`
|
|
201
|
+
|
|
202
|
+
| Option | Type | Default | Description |
|
|
203
|
+
| ----------------- | --------- | ------- | ---------------------------- |
|
|
204
|
+
| `enableReconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
|
|
205
|
+
|
|
206
|
+
## Binary Streams
|
|
207
|
+
|
|
208
|
+
`SrpcByteStream` provides multiplexed binary streaming over existing SRPC connections. Streams are `Duplex` node streams with backpressure support.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
// Sender side
|
|
212
|
+
const sender = SrpcByteStream.createSender(stream);
|
|
213
|
+
sender.write(buffer);
|
|
214
|
+
sender.end();
|
|
215
|
+
|
|
216
|
+
// Receiver side (via handler)
|
|
217
|
+
const receiver = SrpcByteStream.createReceiver(stream, streamId);
|
|
218
|
+
receiver.on('data', chunk => {
|
|
219
|
+
/* process binary data */
|
|
220
|
+
});
|
|
221
|
+
receiver.on('end', () => {
|
|
222
|
+
/* stream finished */
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Constants
|
|
227
|
+
|
|
228
|
+
| Constant | Value | Description |
|
|
229
|
+
| ---------------------------- | --------- | ------------------------------------------- |
|
|
230
|
+
| `HIGH_WATER_MARK` | 256 KB | WebSocket buffer threshold for backpressure |
|
|
231
|
+
| `PENDING_RECEIVER_MAX_BYTES` | 2 MB | Max buffer before receiver is created |
|
|
232
|
+
| `PENDING_RECEIVER_TTL_MS` | 5 seconds | Timeout for pending receiver data |
|
|
233
|
+
|
|
234
|
+
## Disconnect Causes
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
type SrpcDisconnectCause = 'disconnect' | 'duplicate' | 'timeout' | 'badArg';
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
| Cause | Description |
|
|
241
|
+
| ------------ | ------------------------------------------ |
|
|
242
|
+
| `disconnect` | Normal disconnection |
|
|
243
|
+
| `duplicate` | Another connection with the same client ID |
|
|
244
|
+
| `timeout` | Heartbeat timeout |
|
|
245
|
+
| `badArg` | Invalid connection arguments |
|
|
246
|
+
|
|
247
|
+
## Error Handling
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
import { SrpcError } from '@zyno-io/dk-server-foundation';
|
|
251
|
+
|
|
252
|
+
// Throw user-facing errors in handlers
|
|
253
|
+
throw new SrpcError('Invalid input', true); // isUserError: true
|
|
254
|
+
|
|
255
|
+
// Non-user errors are logged but return generic message to client
|
|
256
|
+
throw new SrpcError('Internal failure', false);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## OpenTelemetry Integration
|
|
260
|
+
|
|
261
|
+
SRPC automatically propagates trace context between client and server. Spans are created for each RPC call with the message prefix as the span name.
|