@signal24/dk-server-foundation 26.213.615
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/.gitattributes +2 -0
- package/.gitlab-ci.yml +49 -0
- package/.oxlintrc.json +40 -0
- package/.prettierignore +3 -0
- package/.prettierrc.json +15 -0
- package/.serena/project.yml +111 -0
- package/.vscode/launch.json +15 -0
- package/.vscode/settings.json +12 -0
- package/.yarnrc.yml +5 -0
- package/CLAUDE.md +279 -0
- package/LICENSE +21 -0
- package/README.md +439 -0
- package/TEST_MIGRATION_GUIDE.md +348 -0
- package/dist/resources/proto/generated/test/test.d.ts +224 -0
- package/dist/resources/proto/generated/test/test.d.ts.map +1 -0
- package/dist/resources/proto/generated/test/test.js +2376 -0
- package/dist/resources/proto/generated/test/test.js.map +1 -0
- package/dist/src/app/base.d.ts +37 -0
- package/dist/src/app/base.d.ts.map +1 -0
- package/dist/src/app/base.js +244 -0
- package/dist/src/app/base.js.map +1 -0
- package/dist/src/app/config.d.ts +91 -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 +6 -0
- package/dist/src/app/dev.d.ts.map +1 -0
- package/dist/src/app/dev.js +78 -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 +359 -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 +91 -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 +11 -0
- package/dist/src/database/migration/MigrationResetCommand.d.ts.map +1 -0
- package/dist/src/database/migration/MigrationResetCommand.js +149 -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 +104 -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 +408 -0
- package/dist/src/database/migration/create/entity-reader.js.map +1 -0
- package/dist/src/database/migration/create/file-generator.d.ts +2 -0
- package/dist/src/database/migration/create/file-generator.d.ts.map +1 -0
- package/dist/src/database/migration/create/file-generator.js +55 -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 +2 -0
- package/dist/src/database/migration/helpers.d.ts.map +1 -0
- package/dist/src/database/migration/helpers.js +8 -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/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 +8 -0
- package/dist/src/health/healthcheck.service.d.ts.map +1 -0
- package/dist/src/health/healthcheck.service.js +20 -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 +12 -0
- package/dist/src/helpers/redis/broadcast.d.ts.map +1 -0
- package/dist/src/helpers/redis/broadcast.js +99 -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.d.ts +5 -0
- package/dist/src/services/cli/repl.d.ts.map +1 -0
- package/dist/src/services/cli/repl.js +71 -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 +70 -0
- package/dist/src/services/worker/bootstrap.js.map +1 -0
- package/dist/src/services/worker/cli.d.ts +23 -0
- package/dist/src/services/worker/cli.d.ts.map +1 -0
- package/dist/src/services/worker/cli.js +81 -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/observer.d.ts +18 -0
- package/dist/src/services/worker/observer.d.ts.map +1 -0
- package/dist/src/services/worker/observer.js +172 -0
- package/dist/src/services/worker/observer.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 +31 -0
- package/dist/src/services/worker/queue.js.map +1 -0
- package/dist/src/services/worker/runner.d.ts +17 -0
- package/dist/src/services/worker/runner.d.ts.map +1 -0
- package/dist/src/services/worker/runner.js +131 -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 +54 -0
- package/dist/src/srpc/SrpcServer.d.ts.map +1 -0
- package/dist/src/srpc/SrpcServer.js +456 -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 +129 -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/testapp/bootstrap.d.ts +1 -0
- package/dist/src/testapp/bootstrap.d.ts.map +1 -0
- package/dist/src/testapp/bootstrap.js +18 -0
- package/dist/src/testapp/bootstrap.js.map +1 -0
- package/dist/src/testapp/sample.d.ts +6 -0
- package/dist/src/testapp/sample.d.ts.map +1 -0
- package/dist/src/testapp/sample.js +228 -0
- package/dist/src/testapp/sample.js.map +1 -0
- package/dist/src/testapp/srpc-test.d.ts +27 -0
- package/dist/src/testapp/srpc-test.d.ts.map +1 -0
- package/dist/src/testapp/srpc-test.js +570 -0
- package/dist/src/testapp/srpc-test.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/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/README.md +38 -0
- package/docs/authentication.md +215 -0
- package/docs/cli.md +302 -0
- package/docs/configuration.md +176 -0
- package/docs/database.md +422 -0
- package/docs/getting-started.md +154 -0
- package/docs/health.md +53 -0
- package/docs/helpers.md +436 -0
- package/docs/http.md +253 -0
- package/docs/leader-service.md +98 -0
- package/docs/logging.md +150 -0
- package/docs/mail.md +161 -0
- package/docs/mesh-service.md +204 -0
- package/docs/srpc.md +261 -0
- package/docs/telemetry.md +166 -0
- package/docs/testing.md +222 -0
- package/docs/types.md +215 -0
- package/docs/worker.md +174 -0
- package/lefthook.yml +12 -0
- package/openapi.yaml +109 -0
- package/package.json +133 -0
- package/patches/@deepkit+type+1.0.19.patch +38 -0
- package/resources/proto/generated/test/test.ts +2721 -0
- package/resources/proto/sample.proto +85 -0
- package/resources/proto/test.proto +178 -0
- package/src/app/base.ts +257 -0
- package/src/app/config.loader.ts +66 -0
- package/src/app/config.ts +120 -0
- package/src/app/const.ts +4 -0
- package/src/app/dev.ts +70 -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 +363 -0
- package/src/cli/dksf-gen-proto.ts +176 -0
- package/src/cli/dksf-install.ts +11 -0
- package/src/cli/dksf-test.ts +95 -0
- package/src/cli/dksf-update.ts +101 -0
- package/src/database/CLAUDE.md +390 -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 +152 -0
- package/src/database/migration/MigrationRunCommand.ts +118 -0
- package/src/database/migration/characters.ts +53 -0
- package/src/database/migration/create/MigrationCreateCommand.ts +94 -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 +462 -0
- package/src/database/migration/create/file-generator.ts +52 -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 +3 -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/health/health.module.ts +30 -0
- package/src/health/healthcheck.controller.ts +17 -0
- package/src/health/healthcheck.service.ts +15 -0
- package/src/health/index.ts +2 -0
- package/src/helpers/CLAUDE.md +71 -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 +94 -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.ts +67 -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/CLAUDE.md +77 -0
- package/src/services/worker/bootstrap.ts +58 -0
- package/src/services/worker/cli.ts +63 -0
- package/src/services/worker/entity.ts +22 -0
- package/src/services/worker/index.ts +30 -0
- package/src/services/worker/observer.ts +180 -0
- package/src/services/worker/queue.ts +34 -0
- package/src/services/worker/runner.ts +146 -0
- package/src/services/worker/types.ts +32 -0
- package/src/srpc/CLAUDE.md +194 -0
- package/src/srpc/SRPC_MIGRATION_GUIDE.md +348 -0
- package/src/srpc/SrpcByteStream.ts +382 -0
- package/src/srpc/SrpcClient.ts +512 -0
- package/src/srpc/SrpcServer.ts +575 -0
- package/src/srpc/index.ts +15 -0
- package/src/srpc/types.ts +144 -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/testapp/bootstrap.ts +17 -0
- package/src/testapp/sample.ts +220 -0
- package/src/testapp/srpc-test.ts +684 -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/tests/app/app.spec.ts +53 -0
- package/tests/app/type.spec.ts +22 -0
- package/tests/auth/jwt.spec.ts +90 -0
- package/tests/database/entity.spec.ts +382 -0
- package/tests/database/locks.spec.ts +142 -0
- package/tests/database/migration-create-integration.spec.ts +234 -0
- package/tests/database/migration-create-unit.spec.ts +3896 -0
- package/tests/helpers/array.spec.ts +80 -0
- package/tests/helpers/cache.spec.ts +202 -0
- package/tests/helpers/crypto.spec.ts +236 -0
- package/tests/helpers/date.spec.ts +94 -0
- package/tests/helpers/error.spec.ts +233 -0
- package/tests/helpers/mutex.spec.ts +354 -0
- package/tests/helpers/objects.spec.ts +212 -0
- package/tests/helpers/package.spec.ts +90 -0
- package/tests/helpers/promise.spec.ts +119 -0
- package/tests/helpers/redis.spec.ts +50 -0
- package/tests/helpers/serialization.spec.ts +150 -0
- package/tests/helpers/stream.spec.ts +225 -0
- package/tests/helpers/validation.spec.ts +133 -0
- package/tests/services/leader.spec.ts +257 -0
- package/tests/services/logger.spec.ts +269 -0
- package/tests/services/mesh.spec.ts +814 -0
- package/tests/shared/db.ts +105 -0
- package/tests/shared/globalSetup.ts +48 -0
- package/tests/shared/helpers.ts +40 -0
- package/tests/srpc/SrpcByteStream.spec.ts +542 -0
- package/tests/tsconfig.json +4 -0
- package/tests/types/index.spec.ts +60 -0
- package/tests/types/phone.spec.ts +140 -0
- package/tsconfig.json +106 -0
- package/tsconfig.test.json +8 -0
- package/types.d.ts +6 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Worker System
|
|
2
|
+
|
|
3
|
+
The worker system integrates BullMQ to queue background jobs and Deepkit services to run them. Enabling workers wires together the queue registry, runner, observer, CLI commands, and the `_jobs` audit table.
|
|
4
|
+
|
|
5
|
+
## Enabling Workers
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { createApp } from '../app';
|
|
9
|
+
|
|
10
|
+
const app = createApp({
|
|
11
|
+
config: MyConfig,
|
|
12
|
+
enableWorker: true
|
|
13
|
+
// …
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
When `enableWorker` is set:
|
|
18
|
+
|
|
19
|
+
- `WorkerService` becomes injectable for queueing jobs.
|
|
20
|
+
- `WorkerRunnerService` and `WorkerObserverService` are registered (but only started when appropriate).
|
|
21
|
+
- CLI controllers (`worker:start`, `worker:runner`, `worker:observer`, `worker:queue`) become available.
|
|
22
|
+
- `JobEntity` is added to the database schema to persist job lifecycle data.
|
|
23
|
+
|
|
24
|
+
At runtime, the runner/observer auto-start in non-production environments. In production, toggle them with configuration flags (`ENABLE_JOB_RUNNER`, `ENABLE_JOB_OBSERVER`). They can also be launched explicitly through the CLI commands listed above.
|
|
25
|
+
|
|
26
|
+
## Defining Jobs
|
|
27
|
+
|
|
28
|
+
Jobs extend `BaseJob` and are annotated with the `@WorkerJob()` decorator so the runner can discover them:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { BaseJob, WorkerJob } from '../services/worker';
|
|
32
|
+
|
|
33
|
+
@WorkerJob()
|
|
34
|
+
class SendEmailJob extends BaseJob<{ to: string; subject: string }, void> {
|
|
35
|
+
constructor(private mailer: MailService) {
|
|
36
|
+
super();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async handle(data: { to: string; subject: string }) {
|
|
40
|
+
await this.mailer.send(data.to, data.subject);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Optional static configuration:
|
|
46
|
+
|
|
47
|
+
- `QUEUE_NAME` – assign the job to a named queue (defaults to the app's `BULL_QUEUE`).
|
|
48
|
+
- `CRON_SCHEDULE` – schedule recurring execution using a cron pattern (registered automatically when the runner starts).
|
|
49
|
+
|
|
50
|
+
The job instance receives dependencies via Deepkit's injector. There is no BullMQ `Job` object injected—log additional context yourself if needed.
|
|
51
|
+
|
|
52
|
+
## Queueing Jobs
|
|
53
|
+
|
|
54
|
+
Use `WorkerService.queueJob()` from request handlers or other services:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
class NotificationController {
|
|
58
|
+
constructor(private worker: WorkerService) {}
|
|
59
|
+
|
|
60
|
+
async sendWelcome(to: string) {
|
|
61
|
+
await this.worker.queueJob(SendEmailJob, { to, subject: 'Welcome!' });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`queueJob` accepts an optional `{ delay?: number }` option. When running in test environment (`APP_ENV=test`), the method simply logs a warning and skips queueing to keep tests deterministic.
|
|
67
|
+
|
|
68
|
+
## Runner & Observer
|
|
69
|
+
|
|
70
|
+
- **WorkerRunnerService** pulls jobs from the configured BullMQ queue and invokes the `handle()` method. It resolves job classes registered with `@WorkerJob()` and honours `CRON_SCHEDULE`.
|
|
71
|
+
- **WorkerObserverService** listens for BullMQ lifecycle events, writes entries to the `_jobs` table via `JobEntity`, and clears completed/failed jobs from Redis after logging. It also wires into the health-check system to ensure Redis remains reachable.
|
|
72
|
+
|
|
73
|
+
Both services close BullMQ resources during shutdown and support graceful termination through the Deepkit event system.
|
|
74
|
+
|
|
75
|
+
## Redis & Configuration
|
|
76
|
+
|
|
77
|
+
All worker components share Redis connection settings derived from `BaseAppConfig` (e.g. `BULL_QUEUE`, `REDIS_HOST` or sentinel configuration). Ensure these values are populated before starting the app or dedicated worker processes.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { App } from '@deepkit/app';
|
|
2
|
+
import { eventDispatcher } from '@deepkit/event';
|
|
3
|
+
import { onServerMainBootstrapDone, onServerShutdown } from '@deepkit/framework';
|
|
4
|
+
import { Redis } from 'ioredis';
|
|
5
|
+
|
|
6
|
+
import { getAppConfig } from '../../app/resolver';
|
|
7
|
+
import { isDevelopment } from '../../app/const';
|
|
8
|
+
import { globalState } from '../../app/state';
|
|
9
|
+
import { WorkerQueueJobCommand, WorkerStartCommand, WorkerStartObserverCommand, WorkerStartRunnerCommand } from './cli';
|
|
10
|
+
import { JobEntity } from './entity';
|
|
11
|
+
import { WorkerObserverService } from './observer';
|
|
12
|
+
import { WorkerQueueRegistry } from './queue';
|
|
13
|
+
import { WorkerRunnerService } from './runner';
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
export function installWorkerComponents(app: App<any>) {
|
|
17
|
+
globalState.enableWorker = true;
|
|
18
|
+
globalState.additionalEntities.push(JobEntity);
|
|
19
|
+
|
|
20
|
+
app.appModule.addProvider(WorkerObserverService);
|
|
21
|
+
app.appModule.addProvider(WorkerRunnerService);
|
|
22
|
+
|
|
23
|
+
app.appModule.addController(WorkerStartCommand);
|
|
24
|
+
app.appModule.addController(WorkerStartRunnerCommand);
|
|
25
|
+
app.appModule.addController(WorkerStartObserverCommand);
|
|
26
|
+
app.appModule.addController(WorkerQueueJobCommand);
|
|
27
|
+
|
|
28
|
+
class WorkerListener {
|
|
29
|
+
constructor(private runner: WorkerRunnerService) {}
|
|
30
|
+
|
|
31
|
+
@eventDispatcher.listen(onServerShutdown)
|
|
32
|
+
async shutdownRunner() {
|
|
33
|
+
await this.runner.shutdown();
|
|
34
|
+
|
|
35
|
+
// prevent new Redis connections from being created after shutdown
|
|
36
|
+
// some issue in dev keeping processes alive forever
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
(Redis.prototype as any).connect = () => {};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// we want this to run very late in the process, after the worker and observer have shut down
|
|
42
|
+
@eventDispatcher.listen(onServerShutdown, 1000)
|
|
43
|
+
async closeQueues() {
|
|
44
|
+
await WorkerQueueRegistry.closeQueues();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
app.appModule.addListener(WorkerListener);
|
|
48
|
+
|
|
49
|
+
app.listen(onServerMainBootstrapDone, () => {
|
|
50
|
+
if (!globalState.isCliService) {
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
const config = getAppConfig();
|
|
53
|
+
if (config.ENABLE_JOB_OBSERVER ?? isDevelopment) app.get(WorkerObserverService).start();
|
|
54
|
+
if (config.ENABLE_JOB_RUNNER ?? isDevelopment) app.get(WorkerRunnerService).start();
|
|
55
|
+
}, 1000);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { cli } from '@deepkit/app';
|
|
2
|
+
|
|
3
|
+
import { CliServiceCommand } from '../cli';
|
|
4
|
+
import { WorkerObserverService } from './observer';
|
|
5
|
+
import { WorkerQueueRegistry } from './queue';
|
|
6
|
+
import { WorkerRunnerService } from './runner';
|
|
7
|
+
import { BaseJob } from './types';
|
|
8
|
+
|
|
9
|
+
@cli.controller('worker:start', {
|
|
10
|
+
description: 'Start the worker runner and observer'
|
|
11
|
+
})
|
|
12
|
+
export class WorkerStartCommand extends CliServiceCommand {
|
|
13
|
+
constructor(
|
|
14
|
+
private runner: WorkerRunnerService,
|
|
15
|
+
private observer: WorkerObserverService
|
|
16
|
+
) {
|
|
17
|
+
super();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async startService() {
|
|
21
|
+
await this.runner.start();
|
|
22
|
+
await this.observer.start();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@cli.controller('worker:runner', {
|
|
27
|
+
description: 'Start the worker runner'
|
|
28
|
+
})
|
|
29
|
+
export class WorkerStartRunnerCommand extends CliServiceCommand {
|
|
30
|
+
constructor(private runner: WorkerRunnerService) {
|
|
31
|
+
super();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async startService() {
|
|
35
|
+
await this.runner.start();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@cli.controller('worker:observer', {
|
|
40
|
+
description: 'Start the worker observer'
|
|
41
|
+
})
|
|
42
|
+
export class WorkerStartObserverCommand extends CliServiceCommand {
|
|
43
|
+
constructor(private observer: WorkerObserverService) {
|
|
44
|
+
super();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async startService() {
|
|
48
|
+
await this.observer.start();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@cli.controller('worker:queue', {
|
|
53
|
+
// todo: optional queue name?
|
|
54
|
+
description: 'Queue a job by name'
|
|
55
|
+
})
|
|
56
|
+
export class WorkerQueueJobCommand {
|
|
57
|
+
async execute(jobName: string, data?: string) {
|
|
58
|
+
data = data ? JSON.parse(data) : {};
|
|
59
|
+
const queue = WorkerQueueRegistry.getQueue(BaseJob.QUEUE_NAME);
|
|
60
|
+
await queue.add(jobName, data);
|
|
61
|
+
await queue.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { entity, Index, PrimaryKey } from '@deepkit/type';
|
|
2
|
+
|
|
3
|
+
import { BaseEntity } from '../../database';
|
|
4
|
+
|
|
5
|
+
@entity.name('_jobs')
|
|
6
|
+
export class JobEntity extends BaseEntity {
|
|
7
|
+
id!: string & PrimaryKey;
|
|
8
|
+
queue!: string & Index;
|
|
9
|
+
queueId!: string;
|
|
10
|
+
attempt!: number;
|
|
11
|
+
name!: string;
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
+
data!: any;
|
|
14
|
+
traceId!: string | null;
|
|
15
|
+
status!: 'completed' | 'failed';
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
result!: any;
|
|
18
|
+
createdAt!: Date;
|
|
19
|
+
shouldExecuteAt!: Date;
|
|
20
|
+
executedAt!: Date;
|
|
21
|
+
completedAt!: Date;
|
|
22
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ClassType } from '@deepkit/core';
|
|
2
|
+
|
|
3
|
+
import { isTest } from '../../app/const';
|
|
4
|
+
import { createLogger } from '../logger';
|
|
5
|
+
import { WorkerQueueRegistry } from './queue';
|
|
6
|
+
import { BaseJob, IJobOptions, InputDataSymbol, JobClass } from './types';
|
|
7
|
+
|
|
8
|
+
export * from './entity';
|
|
9
|
+
export { BaseJob, WorkerJob } from './types';
|
|
10
|
+
|
|
11
|
+
export class WorkerService {
|
|
12
|
+
private logger = createLogger(this);
|
|
13
|
+
|
|
14
|
+
async queueJob<I extends object, O, T extends BaseJob<I, O>>(jobClass: ClassType<T>, data: T[typeof InputDataSymbol], options?: IJobOptions) {
|
|
15
|
+
if (isTest) {
|
|
16
|
+
this.logger.warn('Not queueing job in test environment', { jobName: jobClass.name, data, options });
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const typedJob = jobClass as unknown as JobClass;
|
|
22
|
+
const queue = WorkerQueueRegistry.getQueue(typedJob.QUEUE_NAME);
|
|
23
|
+
const job = await queue.add(jobClass.name, data, options);
|
|
24
|
+
this.logger.info('Queued job', { job: { name: jobClass.name, id: job.id } });
|
|
25
|
+
} catch (err) {
|
|
26
|
+
this.logger.error('Failed to queue job', err, { job: { name: jobClass.name } });
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { UniqueConstraintFailure } from '@deepkit/orm';
|
|
2
|
+
import { SQLDatabaseAdapter } from '@deepkit/sql';
|
|
3
|
+
import { Job, QueueEvents } from 'bullmq';
|
|
4
|
+
|
|
5
|
+
import { getAppConfig } from '../../app/resolver';
|
|
6
|
+
import { DBProvider } from '../../app/state';
|
|
7
|
+
import { createPersistedEntity, getDialect, tableExistsSql } from '../../database';
|
|
8
|
+
import { HealthcheckService } from '../../health/healthcheck.service';
|
|
9
|
+
import { createRedisOptions } from '../../helpers/redis/redis';
|
|
10
|
+
import { createLogger, ExtendedLogger } from '../logger';
|
|
11
|
+
import { JobEntity } from './entity';
|
|
12
|
+
import { WorkerQueueRegistry } from './queue';
|
|
13
|
+
import { BaseAppConfig } from '../../app';
|
|
14
|
+
|
|
15
|
+
export class WorkerObserverService {
|
|
16
|
+
private appConfig: BaseAppConfig;
|
|
17
|
+
private queueName: string;
|
|
18
|
+
private logger: ExtendedLogger;
|
|
19
|
+
private observer?: QueueEvents;
|
|
20
|
+
private db = this.dbProvider.db;
|
|
21
|
+
|
|
22
|
+
constructor(
|
|
23
|
+
private hcSvc: HealthcheckService,
|
|
24
|
+
private dbProvider: DBProvider
|
|
25
|
+
) {
|
|
26
|
+
this.appConfig = getAppConfig();
|
|
27
|
+
this.queueName = this.appConfig.BULL_QUEUE;
|
|
28
|
+
this.logger = createLogger(this, { queueName: this.queueName });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async start() {
|
|
32
|
+
await this.ensureTableExists();
|
|
33
|
+
|
|
34
|
+
const { options, prefix } = createRedisOptions('BULL');
|
|
35
|
+
this.observer = new QueueEvents(this.queueName, {
|
|
36
|
+
connection: options,
|
|
37
|
+
prefix: `${prefix}:bmq`
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const queue = WorkerQueueRegistry.getQueue(this.appConfig.BULL_QUEUE);
|
|
41
|
+
|
|
42
|
+
this.observer.on('added', args => {
|
|
43
|
+
this.logger.info('Job added', {
|
|
44
|
+
jobId: args.jobId,
|
|
45
|
+
jobName: args.name
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
this.observer.on('active', args => {
|
|
49
|
+
this.logger.info('Job activated', { jobId: args.jobId });
|
|
50
|
+
});
|
|
51
|
+
this.observer.on('stalled', args => {
|
|
52
|
+
this.logger.warn('Job stalled', { jobId: args.jobId });
|
|
53
|
+
});
|
|
54
|
+
this.observer.on('delayed', args => {
|
|
55
|
+
this.logger.info('Job delayed', { jobId: args.jobId, delay: args.delay });
|
|
56
|
+
});
|
|
57
|
+
this.observer.on('completed', async args => {
|
|
58
|
+
this.logger.info('Job completed', { jobId: args.jobId });
|
|
59
|
+
const job = await queue.getJob(args.jobId);
|
|
60
|
+
if (job) {
|
|
61
|
+
await this.logJob(job, 'completed', args.returnvalue);
|
|
62
|
+
await queue.remove(job.id!);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
this.observer.on('failed', async args => {
|
|
66
|
+
this.logger.info('Job failed', { jobId: args.jobId });
|
|
67
|
+
const job = await queue.getJob(args.jobId);
|
|
68
|
+
if (job) {
|
|
69
|
+
await this.logJob(job, 'failed', { reason: job.failedReason, stack: job.failedReason });
|
|
70
|
+
await queue.remove(job.id!);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
this.observer.on('error', err => {
|
|
74
|
+
this.logger.error('Observer error:', err);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
this.logger.info('Observer started');
|
|
78
|
+
|
|
79
|
+
const completedJobs = await queue.getCompleted();
|
|
80
|
+
for (const job of completedJobs) {
|
|
81
|
+
this.logger.info('Logging previously completed job', { jobId: job.id });
|
|
82
|
+
await this.logJob(job, 'completed', job.returnvalue);
|
|
83
|
+
await queue.remove(job.id!);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const failedJobs = await queue.getFailed();
|
|
87
|
+
for (const job of failedJobs) {
|
|
88
|
+
this.logger.error('Logging previously failed job', { jobId: job.id });
|
|
89
|
+
await this.logJob(job, 'failed', { reason: job.failedReason, stack: job.stacktrace });
|
|
90
|
+
await queue.remove(job.id!);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.hcSvc.register(async () => {
|
|
94
|
+
if (!this.isRedisReady()) {
|
|
95
|
+
throw new Error('Observer Redis connection is not ready');
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private isRedisReady() {
|
|
101
|
+
return this.observer?.['connection']['_client'].status === 'ready' || this.observer?.['connection']['_client'].status === 'wait';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private async ensureTableExists() {
|
|
105
|
+
const dialect = getDialect(this.db.adapter as SQLDatabaseAdapter);
|
|
106
|
+
const tableInfoRows = await this.db.rawQuery(tableExistsSql(dialect, '_jobs'));
|
|
107
|
+
if (tableInfoRows.length) return;
|
|
108
|
+
|
|
109
|
+
if (dialect === 'postgres') {
|
|
110
|
+
await this.db.rawExecute(`
|
|
111
|
+
CREATE TABLE "_jobs" (
|
|
112
|
+
"id" varchar(255) NOT NULL,
|
|
113
|
+
"queue" varchar(255) NOT NULL,
|
|
114
|
+
"queueId" varchar(255) NOT NULL,
|
|
115
|
+
"attempt" smallint NOT NULL,
|
|
116
|
+
"name" varchar(255) NOT NULL,
|
|
117
|
+
"data" jsonb DEFAULT NULL,
|
|
118
|
+
"traceId" char(32) DEFAULT NULL,
|
|
119
|
+
"status" varchar(20) NOT NULL CHECK ("status" IN ('completed','failed')),
|
|
120
|
+
"result" jsonb DEFAULT NULL,
|
|
121
|
+
"createdAt" timestamp NOT NULL,
|
|
122
|
+
"shouldExecuteAt" timestamp NOT NULL,
|
|
123
|
+
"executedAt" timestamp NOT NULL,
|
|
124
|
+
"completedAt" timestamp NOT NULL,
|
|
125
|
+
PRIMARY KEY ("id","attempt")
|
|
126
|
+
);
|
|
127
|
+
`);
|
|
128
|
+
} else {
|
|
129
|
+
await this.db.rawExecute(`
|
|
130
|
+
CREATE TABLE \`_jobs\` (
|
|
131
|
+
\`id\` varchar(255) NOT NULL,
|
|
132
|
+
\`queue\` varchar(255) NOT NULL,
|
|
133
|
+
\`queueId\` varchar(255) NOT NULL,
|
|
134
|
+
\`attempt\` tinyint unsigned NOT NULL,
|
|
135
|
+
\`name\` varchar(255) NOT NULL,
|
|
136
|
+
\`data\` json DEFAULT NULL,
|
|
137
|
+
\`traceId\` char(32) DEFAULT NULL,
|
|
138
|
+
\`status\` enum('completed','failed') NOT NULL,
|
|
139
|
+
\`result\` json DEFAULT NULL,
|
|
140
|
+
\`createdAt\` datetime NOT NULL,
|
|
141
|
+
\`shouldExecuteAt\` datetime NOT NULL,
|
|
142
|
+
\`executedAt\` datetime NOT NULL,
|
|
143
|
+
\`completedAt\` datetime NOT NULL,
|
|
144
|
+
PRIMARY KEY (\`id\`,\`attempt\`)
|
|
145
|
+
) ENGINE=InnoDB;
|
|
146
|
+
`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
151
|
+
async logJob(job: Job, status: 'completed' | 'failed', result: any) {
|
|
152
|
+
try {
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
154
|
+
const traceparent = (job.opts as any).traceparent;
|
|
155
|
+
const traceId = traceparent ? traceparent.split('-')[1] : null;
|
|
156
|
+
|
|
157
|
+
await createPersistedEntity(JobEntity, {
|
|
158
|
+
id: `${this.queueName}:${job.id}`,
|
|
159
|
+
queue: this.queueName,
|
|
160
|
+
queueId: job.id!,
|
|
161
|
+
attempt: job.attemptsMade,
|
|
162
|
+
name: job.name,
|
|
163
|
+
data: job.data,
|
|
164
|
+
traceId,
|
|
165
|
+
status,
|
|
166
|
+
result,
|
|
167
|
+
createdAt: new Date(job.timestamp),
|
|
168
|
+
shouldExecuteAt: new Date(job.timestamp + (job.opts.delay ?? 0)),
|
|
169
|
+
executedAt: new Date(job.processedOn!),
|
|
170
|
+
completedAt: new Date(job.finishedOn!)
|
|
171
|
+
});
|
|
172
|
+
} catch (err) {
|
|
173
|
+
if (err instanceof UniqueConstraintFailure) {
|
|
174
|
+
this.logger.warn('Job already logged', { jobId: job.id });
|
|
175
|
+
} else {
|
|
176
|
+
throw err;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Queue } from 'bullmq';
|
|
2
|
+
|
|
3
|
+
import { getAppConfig } from '../../app/resolver';
|
|
4
|
+
import { createRedisOptions } from '../../helpers/redis/redis';
|
|
5
|
+
|
|
6
|
+
export class WorkerQueueRegistry {
|
|
7
|
+
static registry = new Map<string, Queue>();
|
|
8
|
+
|
|
9
|
+
static getDefaultQueue() {
|
|
10
|
+
const appConfig = getAppConfig();
|
|
11
|
+
return this.getQueue(appConfig.BULL_QUEUE);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static getQueue(name: string): Queue {
|
|
15
|
+
if (!this.registry.has(name)) {
|
|
16
|
+
const { options, prefix } = createRedisOptions('BULL');
|
|
17
|
+
this.registry.set(
|
|
18
|
+
name,
|
|
19
|
+
new Queue(name, {
|
|
20
|
+
connection: options,
|
|
21
|
+
prefix: `${prefix}:bmq`
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return this.registry.get(name)!;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static async closeQueues() {
|
|
30
|
+
for (const queue of this.registry.values()) {
|
|
31
|
+
await queue.close();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { SpanContext } from '@opentelemetry/api';
|
|
2
|
+
import { Job, Queue, Worker } from 'bullmq';
|
|
3
|
+
|
|
4
|
+
import { BaseAppConfig } from '../../app';
|
|
5
|
+
import { getAppConfig, resolveDeep } from '../../app/resolver';
|
|
6
|
+
import { HealthcheckService } from '../../health/healthcheck.service';
|
|
7
|
+
import { sleepSecs, withContextData } from '../../helpers';
|
|
8
|
+
import { getRegisteredClasses } from '../../helpers/framework/decorators';
|
|
9
|
+
import { createRedisOptions } from '../../helpers/redis/redis';
|
|
10
|
+
import { getTraceContext, setSpanAttributes, withRootSpan } from '../../telemetry';
|
|
11
|
+
import { createLogger, ExtendedLogger } from '../logger';
|
|
12
|
+
import { WorkerQueueRegistry } from './queue';
|
|
13
|
+
import { JobClass, WorkerSymbol } from './types';
|
|
14
|
+
|
|
15
|
+
export class WorkerRunnerService {
|
|
16
|
+
private appConfig: BaseAppConfig;
|
|
17
|
+
private queueName: string;
|
|
18
|
+
private logger: ExtendedLogger;
|
|
19
|
+
private worker?: Worker;
|
|
20
|
+
private queue?: Queue;
|
|
21
|
+
private jobHandlers = new Map<string, InstanceType<JobClass>>();
|
|
22
|
+
private runningJob?: Job;
|
|
23
|
+
|
|
24
|
+
constructor(private hcSvc: HealthcheckService) {
|
|
25
|
+
this.appConfig = getAppConfig();
|
|
26
|
+
this.queueName = this.appConfig.BULL_QUEUE;
|
|
27
|
+
this.logger = createLogger(this, { queue: this.queueName });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async start() {
|
|
31
|
+
this.queue = WorkerQueueRegistry.getQueue(this.queueName);
|
|
32
|
+
|
|
33
|
+
const allJobClasses = getRegisteredClasses<JobClass>(WorkerSymbol);
|
|
34
|
+
|
|
35
|
+
for (const jobClass of allJobClasses) {
|
|
36
|
+
if (jobClass.QUEUE_NAME === this.queueName) {
|
|
37
|
+
this.logger.info('Registering job', { id: { name: jobClass.name, schedule: jobClass.CRON_SCHEDULE } });
|
|
38
|
+
|
|
39
|
+
const handlerInstance = resolveDeep(jobClass);
|
|
40
|
+
if (!handlerInstance) throw new Error(`Cannot resolve job handler: ${jobClass.name}`);
|
|
41
|
+
this.jobHandlers.set(jobClass.name, handlerInstance);
|
|
42
|
+
|
|
43
|
+
if (jobClass.CRON_SCHEDULE) {
|
|
44
|
+
this.queue.add(jobClass.name, {}, { repeat: { pattern: jobClass.CRON_SCHEDULE } });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const { options, prefix } = createRedisOptions('BULL');
|
|
50
|
+
|
|
51
|
+
this.worker = new Worker(
|
|
52
|
+
this.queueName,
|
|
53
|
+
async job =>
|
|
54
|
+
this.withJobSpan(job, () =>
|
|
55
|
+
withContextData(
|
|
56
|
+
{
|
|
57
|
+
job: {
|
|
58
|
+
queue: this.queueName,
|
|
59
|
+
id: job.id,
|
|
60
|
+
name: job.name
|
|
61
|
+
},
|
|
62
|
+
traceId: getTraceContext()?.traceId
|
|
63
|
+
},
|
|
64
|
+
async () => {
|
|
65
|
+
const handler = this.jobHandlers.get(job.name);
|
|
66
|
+
if (!handler) {
|
|
67
|
+
throw new Error(`Job ${job.name} is not registered`);
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
this.runningJob = job;
|
|
71
|
+
return await handler.handle(job.data);
|
|
72
|
+
} finally {
|
|
73
|
+
this.runningJob = undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
),
|
|
78
|
+
{
|
|
79
|
+
concurrency: 1,
|
|
80
|
+
connection: options,
|
|
81
|
+
prefix: `${prefix}:bmq`
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
this.worker.on('active', job => {
|
|
86
|
+
this.logger.info('Job activated', { job: { name: job.name, id: job.id } });
|
|
87
|
+
});
|
|
88
|
+
this.worker.on('completed', job => {
|
|
89
|
+
this.logger.info('Job completed', { job: { name: job.name, id: job.id } });
|
|
90
|
+
});
|
|
91
|
+
this.worker.on('failed', (job, err) => {
|
|
92
|
+
this.logger.error(`Job failed: ${err.message}`, err, { job: job ? { name: job.name, id: job.id } : undefined });
|
|
93
|
+
});
|
|
94
|
+
this.worker.on('stalled', jobId => {
|
|
95
|
+
this.logger.warn('Job stalled', { jobId });
|
|
96
|
+
});
|
|
97
|
+
this.worker.on('error', err => {
|
|
98
|
+
this.logger.error('Worker error', err);
|
|
99
|
+
});
|
|
100
|
+
this.worker.on('ready', () => {
|
|
101
|
+
this.logger.info('Worker ready');
|
|
102
|
+
});
|
|
103
|
+
this.logger.info('Worker started');
|
|
104
|
+
|
|
105
|
+
this.hcSvc.register(async () => {
|
|
106
|
+
if (!this.isRedisReady()) {
|
|
107
|
+
throw new Error('Worker Redis connection is not ready');
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private async withJobSpan<T>(job: Job, fn: () => Promise<T>) {
|
|
113
|
+
if (job.repeatJobKey) {
|
|
114
|
+
let innerSpan: SpanContext | undefined;
|
|
115
|
+
const result = await withRootSpan(`Job ${job.name}`, { jobId: job.id, schedulerTrace: getTraceContext()?.traceId }, () => {
|
|
116
|
+
innerSpan = getTraceContext();
|
|
117
|
+
return fn();
|
|
118
|
+
});
|
|
119
|
+
if (innerSpan) setSpanAttributes({ jobTraceId: innerSpan.traceId });
|
|
120
|
+
return result;
|
|
121
|
+
} else {
|
|
122
|
+
return fn();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private isRedisReady() {
|
|
127
|
+
return this.worker?.['blockingConnection']['_client'].status === 'ready' || this.worker?.['blockingConnection']['_client'].status === 'wait';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async shutdown() {
|
|
131
|
+
// there's something crazy going on with worker shutdown when it hasn't successfully connected to Redis
|
|
132
|
+
if (this.isRedisReady()) {
|
|
133
|
+
await this.worker?.pause(true);
|
|
134
|
+
|
|
135
|
+
while (this.runningJob) {
|
|
136
|
+
this.logger.warn('Waiting for job to finish', { job: { name: this.runningJob.name, id: this.runningJob.id } });
|
|
137
|
+
await sleepSecs(1);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
await this.worker?.close();
|
|
141
|
+
} else {
|
|
142
|
+
this.worker?.close(true);
|
|
143
|
+
this.worker?.disconnect();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ClassType } from '@deepkit/core';
|
|
2
|
+
|
|
3
|
+
import { createRegistryClassDecorator } from '../../helpers/framework/decorators';
|
|
4
|
+
|
|
5
|
+
export const JobSymbol = Symbol('Job');
|
|
6
|
+
export const InputDataSymbol = Symbol('InputData');
|
|
7
|
+
export const OutputDataSymbol = Symbol('OutputData');
|
|
8
|
+
|
|
9
|
+
export const WorkerSymbol = Symbol('Worker');
|
|
10
|
+
export const WorkerJob = createRegistryClassDecorator(WorkerSymbol);
|
|
11
|
+
|
|
12
|
+
export abstract class BaseJob<I = void, O = void> {
|
|
13
|
+
[JobSymbol] = JobSymbol;
|
|
14
|
+
[InputDataSymbol]!: I;
|
|
15
|
+
[OutputDataSymbol]!: O;
|
|
16
|
+
|
|
17
|
+
static QUEUE_NAME = 'default';
|
|
18
|
+
static CRON_SCHEDULE: string | null = null;
|
|
19
|
+
|
|
20
|
+
abstract handle(data: I): Promise<O>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface BaseJobClass {
|
|
24
|
+
QUEUE_NAME: string;
|
|
25
|
+
CRON_SCHEDULE: string | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type JobClass = ClassType<BaseJob> & BaseJobClass;
|
|
29
|
+
|
|
30
|
+
export interface IJobOptions {
|
|
31
|
+
delay?: number;
|
|
32
|
+
}
|