alepha 0.13.7 → 0.14.0
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/README.md +5 -2
- package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui-standalone-preset.js +1 -1
- package/assets/swagger-ui/swagger-ui.css +1 -1
- package/dist/{api-audits → api/audits}/index.browser.js +4 -4
- package/dist/api/audits/index.browser.js.map +1 -0
- package/dist/{api-audits → api/audits}/index.d.ts +10 -9
- package/dist/api/audits/index.d.ts.map +1 -0
- package/dist/{api-audits → api/audits}/index.js +8 -8
- package/dist/api/audits/index.js.map +1 -0
- package/dist/{api-files → api/files}/index.browser.js +5 -5
- package/dist/api/files/index.browser.js.map +1 -0
- package/dist/{api-files → api/files}/index.d.ts +18 -10
- package/dist/api/files/index.d.ts.map +1 -0
- package/dist/{api-files → api/files}/index.js +10 -10
- package/dist/api/files/index.js.map +1 -0
- package/dist/{api-jobs → api/jobs}/index.browser.js +5 -5
- package/dist/api/jobs/index.browser.js.map +1 -0
- package/dist/{api-jobs → api/jobs}/index.d.ts +168 -167
- package/dist/api/jobs/index.d.ts.map +1 -0
- package/dist/{api-jobs → api/jobs}/index.js +9 -9
- package/dist/api/jobs/index.js.map +1 -0
- package/dist/{api-notifications → api/notifications}/index.browser.js +11 -11
- package/dist/api/notifications/index.browser.js.map +1 -0
- package/dist/api/notifications/index.d.ts +327 -0
- package/dist/api/notifications/index.d.ts.map +1 -0
- package/dist/{api-notifications → api/notifications}/index.js +11 -11
- package/dist/api/notifications/index.js.map +1 -0
- package/dist/{api-parameters → api/parameters}/index.browser.js +2 -2
- package/dist/api/parameters/index.browser.js.map +1 -0
- package/dist/{api-parameters → api/parameters}/index.d.ts +11 -11
- package/dist/api/parameters/index.d.ts.map +1 -0
- package/dist/{api-parameters → api/parameters}/index.js +7 -7
- package/dist/api/parameters/index.js.map +1 -0
- package/dist/{api-users → api/users}/index.browser.js +6 -6
- package/dist/api/users/index.browser.js.map +1 -0
- package/dist/{api-users → api/users}/index.d.ts +836 -836
- package/dist/api/users/index.d.ts.map +1 -0
- package/dist/{api-users → api/users}/index.js +99 -766
- package/dist/api/users/index.js.map +1 -0
- package/dist/{api-verifications → api/verifications}/index.browser.js +5 -5
- package/dist/api/verifications/index.browser.js.map +1 -0
- package/dist/api/verifications/index.d.ts +248 -0
- package/dist/api/verifications/index.d.ts.map +1 -0
- package/dist/{api-verifications → api/verifications}/index.js +11 -11
- package/dist/api/verifications/index.js.map +1 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/bucket/index.d.ts.map +1 -0
- package/dist/cache/{index.d.ts → core/index.d.ts} +4 -4
- package/dist/cache/core/index.d.ts.map +1 -0
- package/dist/cache/{index.js → core/index.js} +5 -5
- package/dist/cache/core/index.js.map +1 -0
- package/dist/{cache-redis → cache/redis}/index.d.ts +2 -2
- package/dist/cache/redis/index.d.ts.map +1 -0
- package/dist/{cache-redis → cache/redis}/index.js +2 -2
- package/dist/cache/redis/index.js.map +1 -0
- package/dist/cli/index.d.ts +78 -58
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +454 -154
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +15 -5
- package/dist/command/index.d.ts.map +1 -0
- package/dist/command/index.js +45 -6
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +1334 -1318
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +75 -71
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +1337 -1321
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +1337 -1321
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts.map +1 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/fake/index.d.ts.map +1 -0
- package/dist/file/index.d.ts.map +1 -0
- package/dist/lock/{index.d.ts → core/index.d.ts} +5 -5
- package/dist/lock/core/index.d.ts.map +1 -0
- package/dist/lock/{index.js → core/index.js} +5 -5
- package/dist/lock/core/index.js.map +1 -0
- package/dist/{lock-redis → lock/redis}/index.d.ts +2 -2
- package/dist/lock/redis/index.d.ts.map +1 -0
- package/dist/{lock-redis → lock/redis}/index.js +2 -2
- package/dist/lock/redis/index.js.map +1 -0
- package/dist/logger/index.d.ts +1 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +820 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +978 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/orm/index.d.ts +180 -107
- package/dist/orm/index.d.ts.map +1 -0
- package/dist/orm/index.js +260 -174
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +548 -0
- package/dist/queue/core/index.d.ts.map +1 -0
- package/dist/queue/core/index.js +391 -0
- package/dist/queue/core/index.js.map +1 -0
- package/dist/queue/redis/index.d.ts +28 -0
- package/dist/queue/redis/index.d.ts.map +1 -0
- package/dist/queue/redis/index.js +43 -0
- package/dist/queue/redis/index.js.map +1 -0
- package/dist/redis/index.d.ts.map +1 -0
- package/dist/retry/index.d.ts.map +1 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/scheduler/index.d.ts +1 -1
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +1 -393
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +2 -1413
- package/dist/security/index.js.map +1 -1
- package/dist/{server-auth → server/auth}/index.browser.js +6 -6
- package/dist/server/auth/index.browser.js.map +1 -0
- package/dist/{server-auth → server/auth}/index.d.ts +167 -167
- package/dist/server/auth/index.d.ts.map +1 -0
- package/dist/server/auth/index.js +742 -0
- package/dist/server/auth/index.js.map +1 -0
- package/dist/{server-cache → server/cache}/index.d.ts +2 -2
- package/dist/server/cache/index.d.ts.map +1 -0
- package/dist/{server-cache → server/cache}/index.js +2 -2
- package/dist/server/cache/index.js.map +1 -0
- package/dist/{server-compress → server/compress}/index.d.ts +2 -2
- package/dist/server/compress/index.d.ts.map +1 -0
- package/dist/{server-compress → server/compress}/index.js +2 -2
- package/dist/server/compress/index.js.map +1 -0
- package/dist/{server-cookies → server/cookies}/index.browser.js +3 -3
- package/dist/server/cookies/index.browser.js.map +1 -0
- package/dist/{server-cookies → server/cookies}/index.d.ts +4 -4
- package/dist/server/cookies/index.d.ts.map +1 -0
- package/dist/{server-cookies → server/cookies}/index.js +4 -4
- package/dist/server/cookies/index.js.map +1 -0
- package/dist/server/{index.browser.js → core/index.browser.js} +14 -14
- package/dist/server/core/index.browser.js.map +1 -0
- package/dist/server/{index.d.ts → core/index.d.ts} +36 -36
- package/dist/server/core/index.d.ts.map +1 -0
- package/dist/server/{index.js → core/index.js} +27 -27
- package/dist/server/core/index.js.map +1 -0
- package/dist/{server-cors → server/cors}/index.d.ts +3 -3
- package/dist/server/cors/index.d.ts.map +1 -0
- package/dist/{server-cors → server/cors}/index.js +3 -3
- package/dist/server/cors/index.js.map +1 -0
- package/dist/{server-health → server/health}/index.d.ts +3 -3
- package/dist/server/health/index.d.ts.map +1 -0
- package/dist/{server-health → server/health}/index.js +3 -3
- package/dist/server/health/index.js.map +1 -0
- package/dist/{server-helmet → server/helmet}/index.d.ts +2 -2
- package/dist/server/helmet/index.d.ts.map +1 -0
- package/dist/{server-helmet → server/helmet}/index.js +2 -2
- package/dist/server/helmet/index.js.map +1 -0
- package/dist/{server-links → server/links}/index.browser.js +5 -5
- package/dist/server/links/index.browser.js.map +1 -0
- package/dist/{server-links → server/links}/index.d.ts +40 -40
- package/dist/server/links/index.d.ts.map +1 -0
- package/dist/{server-links → server/links}/index.js +7 -7
- package/dist/server/links/index.js.map +1 -0
- package/dist/{server-metrics → server/metrics}/index.d.ts +2 -2
- package/dist/server/metrics/index.d.ts.map +1 -0
- package/dist/server/metrics/index.js +74 -0
- package/dist/server/metrics/index.js.map +1 -0
- package/dist/{server-multipart → server/multipart}/index.d.ts +2 -2
- package/dist/server/multipart/index.d.ts.map +1 -0
- package/dist/{server-multipart → server/multipart}/index.js +2 -2
- package/dist/server/multipart/index.js.map +1 -0
- package/dist/{server-proxy → server/proxy}/index.d.ts +3 -3
- package/dist/server/proxy/index.d.ts.map +1 -0
- package/dist/{server-proxy → server/proxy}/index.js +3 -3
- package/dist/server/proxy/index.js.map +1 -0
- package/dist/{server-rate-limit → server/rate-limit}/index.d.ts +4 -4
- package/dist/server/rate-limit/index.d.ts.map +1 -0
- package/dist/{server-rate-limit → server/rate-limit}/index.js +4 -4
- package/dist/server/rate-limit/index.js.map +1 -0
- package/dist/{server-security → server/security}/index.browser.js +1 -1
- package/dist/server/security/index.browser.js.map +1 -0
- package/dist/{server-security → server/security}/index.d.ts +4 -4
- package/dist/server/security/index.d.ts.map +1 -0
- package/dist/{server-security → server/security}/index.js +4 -4
- package/dist/server/security/index.js.map +1 -0
- package/dist/{server-static → server/static}/index.d.ts +3 -3
- package/dist/server/static/index.d.ts.map +1 -0
- package/dist/{server-static → server/static}/index.js +3 -3
- package/dist/server/static/index.js.map +1 -0
- package/dist/{server-swagger → server/swagger}/index.d.ts +3 -3
- package/dist/server/swagger/index.d.ts.map +1 -0
- package/dist/{server-swagger → server/swagger}/index.js +4 -4
- package/dist/server/swagger/index.js.map +1 -0
- package/dist/sms/index.d.ts.map +1 -0
- package/dist/thread/index.d.ts.map +1 -0
- package/dist/topic/{index.d.ts → core/index.d.ts} +6 -6
- package/dist/topic/core/index.d.ts.map +1 -0
- package/dist/topic/{index.js → core/index.js} +6 -6
- package/dist/topic/core/index.js.map +1 -0
- package/dist/{topic-redis → topic/redis}/index.d.ts +2 -2
- package/dist/topic/redis/index.d.ts.map +1 -0
- package/dist/{topic-redis → topic/redis}/index.js +2 -2
- package/dist/topic/redis/index.js.map +1 -0
- package/dist/vite/index.d.ts +21 -2
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +48 -19
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts.map +1 -0
- package/package.json +162 -158
- package/src/{api-files → api/files}/index.ts +1 -0
- package/src/{api-parameters → api/parameters}/index.ts +1 -1
- package/src/{api-users → api/users}/primitives/$userRealm.ts +1 -1
- package/src/{api-users → api/users}/providers/UserRealmProvider.ts +6 -7
- package/src/{api-verifications → api/verifications}/index.ts +2 -0
- package/src/cli/apps/AlephaCli.ts +2 -0
- package/src/cli/apps/AlephaPackageBuilderCli.ts +83 -54
- package/src/cli/assets/appRouterTs.ts +1 -1
- package/src/cli/assets/biomeJson.ts +1 -1
- package/src/cli/assets/indexHtml.ts +1 -1
- package/src/cli/assets/mainBrowserTs.ts +1 -1
- package/src/cli/assets/mainTs.ts +9 -10
- package/src/cli/assets/viteConfigTs.ts +1 -1
- package/src/cli/commands/ChangelogCommands.ts +389 -0
- package/src/cli/commands/CoreCommands.ts +10 -6
- package/src/cli/commands/DrizzleCommands.ts +204 -4
- package/src/cli/commands/VerifyCommands.ts +4 -1
- package/src/cli/commands/ViteCommands.ts +46 -25
- package/src/cli/services/AlephaCliUtils.ts +52 -164
- package/src/command/providers/CliProvider.ts +76 -5
- package/src/core/providers/SchemaValidator.ts +24 -2
- package/src/mcp/errors/McpError.ts +72 -0
- package/src/mcp/helpers/jsonrpc.ts +163 -0
- package/src/mcp/index.ts +132 -0
- package/src/mcp/interfaces/McpTypes.ts +248 -0
- package/src/mcp/primitives/$prompt.ts +188 -0
- package/src/mcp/primitives/$resource.ts +171 -0
- package/src/mcp/primitives/$tool.ts +285 -0
- package/src/mcp/providers/McpServerProvider.ts +382 -0
- package/src/mcp/transports/SseMcpTransport.ts +172 -0
- package/src/mcp/transports/StdioMcpTransport.ts +126 -0
- package/src/orm/index.ts +12 -0
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +164 -0
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +3 -1
- package/src/queue/{index.ts → core/index.ts} +2 -3
- package/src/queue/{primitives → core/primitives}/$queue.ts +17 -162
- package/src/queue/core/providers/MemoryQueueProvider.ts +19 -0
- package/src/queue/core/providers/QueueProvider.ts +23 -0
- package/src/queue/core/providers/WorkerProvider.ts +244 -0
- package/src/queue/redis/providers/RedisQueueProvider.ts +31 -0
- package/src/server/{index.ts → core/index.ts} +1 -0
- package/src/{server-rate-limit → server/rate-limit}/index.ts +1 -1
- package/src/{server-swagger → server/swagger}/providers/ServerSwaggerProvider.ts +1 -0
- package/src/vite/plugins/viteAlephaBuild.ts +8 -2
- package/src/vite/plugins/viteAlephaDev.ts +6 -2
- package/src/vite/tasks/buildServer.ts +1 -1
- package/src/vite/tasks/copyAssets.ts +32 -8
- package/src/vite/tasks/generateCloudflare.ts +43 -15
- package/src/vite/tasks/runAlepha.ts +1 -0
- package/dist/api-audits/index.browser.js.map +0 -1
- package/dist/api-audits/index.js.map +0 -1
- package/dist/api-files/index.browser.js.map +0 -1
- package/dist/api-files/index.js.map +0 -1
- package/dist/api-jobs/index.browser.js.map +0 -1
- package/dist/api-jobs/index.js.map +0 -1
- package/dist/api-notifications/index.browser.js.map +0 -1
- package/dist/api-notifications/index.d.ts +0 -327
- package/dist/api-notifications/index.js.map +0 -1
- package/dist/api-parameters/index.browser.js.map +0 -1
- package/dist/api-parameters/index.js.map +0 -1
- package/dist/api-users/index.browser.js.map +0 -1
- package/dist/api-users/index.js.map +0 -1
- package/dist/api-verifications/index.browser.js.map +0 -1
- package/dist/api-verifications/index.d.ts +0 -229
- package/dist/api-verifications/index.js.map +0 -1
- package/dist/cache/index.js.map +0 -1
- package/dist/cache-redis/index.js.map +0 -1
- package/dist/lock/index.js.map +0 -1
- package/dist/lock-redis/index.js.map +0 -1
- package/dist/queue/index.d.ts +0 -1265
- package/dist/queue/index.js +0 -1037
- package/dist/queue/index.js.map +0 -1
- package/dist/queue-redis/index.d.ts +0 -82
- package/dist/queue-redis/index.js +0 -872
- package/dist/queue-redis/index.js.map +0 -1
- package/dist/server/index.browser.js.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/server-auth/index.browser.js.map +0 -1
- package/dist/server-auth/index.js +0 -1973
- package/dist/server-auth/index.js.map +0 -1
- package/dist/server-cache/index.js.map +0 -1
- package/dist/server-compress/index.js.map +0 -1
- package/dist/server-cookies/index.browser.js.map +0 -1
- package/dist/server-cookies/index.js.map +0 -1
- package/dist/server-cors/index.js.map +0 -1
- package/dist/server-health/index.js.map +0 -1
- package/dist/server-helmet/index.js.map +0 -1
- package/dist/server-links/index.browser.js.map +0 -1
- package/dist/server-links/index.js.map +0 -1
- package/dist/server-metrics/index.js +0 -4532
- package/dist/server-metrics/index.js.map +0 -1
- package/dist/server-multipart/index.js.map +0 -1
- package/dist/server-proxy/index.js.map +0 -1
- package/dist/server-rate-limit/index.js.map +0 -1
- package/dist/server-security/index.browser.js.map +0 -1
- package/dist/server-security/index.js.map +0 -1
- package/dist/server-static/index.js.map +0 -1
- package/dist/server-swagger/index.js.map +0 -1
- package/dist/topic/index.js.map +0 -1
- package/dist/topic-redis/index.js.map +0 -1
- package/src/queue/interfaces/QueueJob.ts +0 -459
- package/src/queue/providers/MemoryQueueProvider.ts +0 -850
- package/src/queue/providers/QueueProvider.ts +0 -319
- package/src/queue/providers/WorkerProvider.ts +0 -344
- package/src/queue-redis/providers/RedisQueueProvider.ts +0 -1209
- /package/src/{api-audits → api/audits}/controllers/AuditController.ts +0 -0
- /package/src/{api-audits → api/audits}/entities/audits.ts +0 -0
- /package/src/{api-audits → api/audits}/index.browser.ts +0 -0
- /package/src/{api-audits → api/audits}/index.ts +0 -0
- /package/src/{api-audits → api/audits}/primitives/$audit.ts +0 -0
- /package/src/{api-audits → api/audits}/schemas/auditQuerySchema.ts +0 -0
- /package/src/{api-audits → api/audits}/schemas/auditResourceSchema.ts +0 -0
- /package/src/{api-audits → api/audits}/schemas/createAuditSchema.ts +0 -0
- /package/src/{api-audits → api/audits}/services/AuditService.ts +0 -0
- /package/src/{api-files → api/files}/controllers/FileController.ts +0 -0
- /package/src/{api-files → api/files}/controllers/StorageStatsController.ts +0 -0
- /package/src/{api-files → api/files}/entities/files.ts +0 -0
- /package/src/{api-files → api/files}/index.browser.ts +0 -0
- /package/src/{api-files → api/files}/jobs/FileJobs.ts +0 -0
- /package/src/{api-files → api/files}/schemas/fileQuerySchema.ts +0 -0
- /package/src/{api-files → api/files}/schemas/fileResourceSchema.ts +0 -0
- /package/src/{api-files → api/files}/schemas/storageStatsSchema.ts +0 -0
- /package/src/{api-files → api/files}/services/FileService.ts +0 -0
- /package/src/{api-jobs → api/jobs}/controllers/JobController.ts +0 -0
- /package/src/{api-jobs → api/jobs}/entities/jobExecutions.ts +0 -0
- /package/src/{api-jobs → api/jobs}/index.browser.ts +0 -0
- /package/src/{api-jobs → api/jobs}/index.ts +0 -0
- /package/src/{api-jobs → api/jobs}/primitives/$job.ts +0 -0
- /package/src/{api-jobs → api/jobs}/providers/JobProvider.ts +0 -0
- /package/src/{api-jobs → api/jobs}/schemas/jobExecutionQuerySchema.ts +0 -0
- /package/src/{api-jobs → api/jobs}/schemas/jobExecutionResourceSchema.ts +0 -0
- /package/src/{api-jobs → api/jobs}/schemas/triggerJobSchema.ts +0 -0
- /package/src/{api-jobs → api/jobs}/services/JobService.ts +0 -0
- /package/src/{api-notifications → api/notifications}/controllers/NotificationController.ts +0 -0
- /package/src/{api-notifications → api/notifications}/entities/notifications.ts +0 -0
- /package/src/{api-notifications → api/notifications}/index.browser.ts +0 -0
- /package/src/{api-notifications → api/notifications}/index.ts +0 -0
- /package/src/{api-notifications → api/notifications}/jobs/NotificationJobs.ts +0 -0
- /package/src/{api-notifications → api/notifications}/primitives/$notification.ts +0 -0
- /package/src/{api-notifications → api/notifications}/queues/NotificationQueues.ts +0 -0
- /package/src/{api-notifications → api/notifications}/schemas/notificationContactPreferencesSchema.ts +0 -0
- /package/src/{api-notifications → api/notifications}/schemas/notificationContactSchema.ts +0 -0
- /package/src/{api-notifications → api/notifications}/schemas/notificationCreateSchema.ts +0 -0
- /package/src/{api-notifications → api/notifications}/schemas/notificationQuerySchema.ts +0 -0
- /package/src/{api-notifications → api/notifications}/services/NotificationSenderService.ts +0 -0
- /package/src/{api-notifications → api/notifications}/services/NotificationService.ts +0 -0
- /package/src/{api-parameters → api/parameters}/controllers/ConfigController.ts +0 -0
- /package/src/{api-parameters → api/parameters}/entities/parameters.ts +0 -0
- /package/src/{api-parameters → api/parameters}/index.browser.ts +0 -0
- /package/src/{api-parameters → api/parameters}/primitives/$config.ts +0 -0
- /package/src/{api-parameters → api/parameters}/schedulers/ConfigActivationScheduler.ts +0 -0
- /package/src/{api-parameters → api/parameters}/services/ConfigStore.ts +0 -0
- /package/src/{api-users → api/users}/atoms/realmAuthSettingsAtom.ts +0 -0
- /package/src/{api-users → api/users}/controllers/IdentityController.ts +0 -0
- /package/src/{api-users → api/users}/controllers/SessionController.ts +0 -0
- /package/src/{api-users → api/users}/controllers/UserController.ts +0 -0
- /package/src/{api-users → api/users}/controllers/UserRealmController.ts +0 -0
- /package/src/{api-users → api/users}/entities/identities.ts +0 -0
- /package/src/{api-users → api/users}/entities/sessions.ts +0 -0
- /package/src/{api-users → api/users}/entities/users.ts +0 -0
- /package/src/{api-users → api/users}/index.browser.ts +0 -0
- /package/src/{api-users → api/users}/index.ts +0 -0
- /package/src/{api-users → api/users}/notifications/UserNotifications.ts +0 -0
- /package/src/{api-users → api/users}/schemas/completePasswordResetRequestSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/completeRegistrationRequestSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/createUserSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/identityQuerySchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/identityResourceSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/loginSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/passwordResetIntentResponseSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registerQuerySchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registerRequestSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registerResponseSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registerSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/registrationIntentResponseSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/resetPasswordSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/sessionQuerySchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/sessionResourceSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/updateUserSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/userQuerySchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/userRealmConfigSchema.ts +0 -0
- /package/src/{api-users → api/users}/schemas/userResourceSchema.ts +0 -0
- /package/src/{api-users → api/users}/services/CredentialService.ts +0 -0
- /package/src/{api-users → api/users}/services/IdentityService.ts +0 -0
- /package/src/{api-users → api/users}/services/RegistrationService.ts +0 -0
- /package/src/{api-users → api/users}/services/SessionCrudService.ts +0 -0
- /package/src/{api-users → api/users}/services/SessionService.ts +0 -0
- /package/src/{api-users → api/users}/services/UserService.ts +0 -0
- /package/src/{api-verifications → api/verifications}/controllers/VerificationController.ts +0 -0
- /package/src/{api-verifications → api/verifications}/entities/verifications.ts +0 -0
- /package/src/{api-verifications → api/verifications}/index.browser.ts +0 -0
- /package/src/{api-verifications → api/verifications}/jobs/VerificationJobs.ts +0 -0
- /package/src/{api-verifications → api/verifications}/parameters/VerificationParameters.ts +0 -0
- /package/src/{api-verifications → api/verifications}/schemas/requestVerificationCodeResponseSchema.ts +0 -0
- /package/src/{api-verifications → api/verifications}/schemas/validateVerificationCodeResponseSchema.ts +0 -0
- /package/src/{api-verifications → api/verifications}/schemas/verificationSettingsSchema.ts +0 -0
- /package/src/{api-verifications → api/verifications}/schemas/verificationTypeEnumSchema.ts +0 -0
- /package/src/{api-verifications → api/verifications}/services/VerificationService.ts +0 -0
- /package/src/cache/{errors → core/errors}/CacheError.ts +0 -0
- /package/src/cache/{index.ts → core/index.ts} +0 -0
- /package/src/cache/{primitives → core/primitives}/$cache.ts +0 -0
- /package/src/cache/{providers → core/providers}/CacheProvider.ts +0 -0
- /package/src/cache/{providers → core/providers}/MemoryCacheProvider.ts +0 -0
- /package/src/{cache-redis → cache/redis}/index.ts +0 -0
- /package/src/{cache-redis → cache/redis}/providers/RedisCacheProvider.ts +0 -0
- /package/src/lock/{index.ts → core/index.ts} +0 -0
- /package/src/lock/{primitives → core/primitives}/$lock.ts +0 -0
- /package/src/lock/{providers → core/providers}/LockProvider.ts +0 -0
- /package/src/lock/{providers → core/providers}/LockTopicProvider.ts +0 -0
- /package/src/lock/{providers → core/providers}/MemoryLockProvider.ts +0 -0
- /package/src/{lock-redis → lock/redis}/index.ts +0 -0
- /package/src/{lock-redis → lock/redis}/providers/RedisLockProvider.ts +0 -0
- /package/src/queue/{primitives → core/primitives}/$consumer.ts +0 -0
- /package/src/{queue-redis → queue/redis}/index.ts +0 -0
- /package/src/{server-auth → server/auth}/constants/routes.ts +0 -0
- /package/src/{server-auth → server/auth}/index.browser.ts +0 -0
- /package/src/{server-auth → server/auth}/index.shared.ts +0 -0
- /package/src/{server-auth → server/auth}/index.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$auth.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$authApple.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$authCredentials.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$authGithub.ts +0 -0
- /package/src/{server-auth → server/auth}/primitives/$authGoogle.ts +0 -0
- /package/src/{server-auth → server/auth}/providers/ServerAuthProvider.ts +0 -0
- /package/src/{server-auth → server/auth}/schemas/authenticationProviderSchema.ts +0 -0
- /package/src/{server-auth → server/auth}/schemas/tokenResponseSchema.ts +0 -0
- /package/src/{server-auth → server/auth}/schemas/tokensSchema.ts +0 -0
- /package/src/{server-auth → server/auth}/schemas/userinfoResponseSchema.ts +0 -0
- /package/src/{server-cache → server/cache}/index.ts +0 -0
- /package/src/{server-cache → server/cache}/providers/ServerCacheProvider.ts +0 -0
- /package/src/{server-compress → server/compress}/index.ts +0 -0
- /package/src/{server-compress → server/compress}/providers/ServerCompressProvider.ts +0 -0
- /package/src/{server-cookies → server/cookies}/index.browser.ts +0 -0
- /package/src/{server-cookies → server/cookies}/index.ts +0 -0
- /package/src/{server-cookies → server/cookies}/primitives/$cookie.browser.ts +0 -0
- /package/src/{server-cookies → server/cookies}/primitives/$cookie.ts +0 -0
- /package/src/{server-cookies → server/cookies}/providers/ServerCookiesProvider.ts +0 -0
- /package/src/{server-cookies → server/cookies}/services/CookieParser.ts +0 -0
- /package/src/server/{constants → core/constants}/routeMethods.ts +0 -0
- /package/src/server/{errors → core/errors}/BadRequestError.ts +0 -0
- /package/src/server/{errors → core/errors}/ConflictError.ts +0 -0
- /package/src/server/{errors → core/errors}/ForbiddenError.ts +0 -0
- /package/src/server/{errors → core/errors}/HttpError.ts +0 -0
- /package/src/server/{errors → core/errors}/NotFoundError.ts +0 -0
- /package/src/server/{errors → core/errors}/UnauthorizedError.ts +0 -0
- /package/src/server/{errors → core/errors}/ValidationError.ts +0 -0
- /package/src/server/{helpers → core/helpers}/ServerReply.ts +0 -0
- /package/src/server/{helpers → core/helpers}/isMultipart.ts +0 -0
- /package/src/server/{index.browser.ts → core/index.browser.ts} +0 -0
- /package/src/server/{index.shared.ts → core/index.shared.ts} +0 -0
- /package/src/server/{interfaces → core/interfaces}/ServerRequest.ts +0 -0
- /package/src/server/{primitives → core/primitives}/$action.ts +0 -0
- /package/src/server/{primitives → core/primitives}/$route.ts +0 -0
- /package/src/server/{providers → core/providers}/BunHttpServerProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/NodeHttpServerProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerBodyParserProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerLoggerProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerNotReadyProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerRouterProvider.ts +0 -0
- /package/src/server/{providers → core/providers}/ServerTimingProvider.ts +0 -0
- /package/src/server/{schemas → core/schemas}/errorSchema.ts +0 -0
- /package/src/server/{schemas → core/schemas}/okSchema.ts +0 -0
- /package/src/server/{services → core/services}/HttpClient.ts +0 -0
- /package/src/server/{services → core/services}/ServerRequestParser.ts +0 -0
- /package/src/server/{services → core/services}/UserAgentParser.ts +0 -0
- /package/src/{server-cors → server/cors}/index.ts +0 -0
- /package/src/{server-cors → server/cors}/primitives/$cors.ts +0 -0
- /package/src/{server-cors → server/cors}/providers/ServerCorsProvider.ts +0 -0
- /package/src/{server-health → server/health}/index.ts +0 -0
- /package/src/{server-health → server/health}/providers/ServerHealthProvider.ts +0 -0
- /package/src/{server-health → server/health}/schemas/healthSchema.ts +0 -0
- /package/src/{server-helmet → server/helmet}/index.ts +0 -0
- /package/src/{server-helmet → server/helmet}/providers/ServerHelmetProvider.ts +0 -0
- /package/src/{server-links → server/links}/index.browser.ts +0 -0
- /package/src/{server-links → server/links}/index.ts +0 -0
- /package/src/{server-links → server/links}/primitives/$client.ts +0 -0
- /package/src/{server-links → server/links}/primitives/$remote.ts +0 -0
- /package/src/{server-links → server/links}/providers/LinkProvider.ts +0 -0
- /package/src/{server-links → server/links}/providers/RemotePrimitiveProvider.ts +0 -0
- /package/src/{server-links → server/links}/providers/ServerLinksProvider.ts +0 -0
- /package/src/{server-links → server/links}/schemas/apiLinksResponseSchema.ts +0 -0
- /package/src/{server-metrics → server/metrics}/index.ts +0 -0
- /package/src/{server-metrics → server/metrics}/providers/ServerMetricsProvider.ts +0 -0
- /package/src/{server-multipart → server/multipart}/index.ts +0 -0
- /package/src/{server-multipart → server/multipart}/providers/ServerMultipartProvider.ts +0 -0
- /package/src/{server-proxy → server/proxy}/index.ts +0 -0
- /package/src/{server-proxy → server/proxy}/primitives/$proxy.ts +0 -0
- /package/src/{server-proxy → server/proxy}/providers/ServerProxyProvider.ts +0 -0
- /package/src/{server-rate-limit → server/rate-limit}/primitives/$rateLimit.ts +0 -0
- /package/src/{server-rate-limit → server/rate-limit}/providers/ServerRateLimitProvider.ts +0 -0
- /package/src/{server-security → server/security}/index.browser.ts +0 -0
- /package/src/{server-security → server/security}/index.ts +0 -0
- /package/src/{server-security → server/security}/primitives/$basicAuth.ts +0 -0
- /package/src/{server-security → server/security}/providers/ServerBasicAuthProvider.ts +0 -0
- /package/src/{server-security → server/security}/providers/ServerSecurityProvider.ts +0 -0
- /package/src/{server-static → server/static}/index.ts +0 -0
- /package/src/{server-static → server/static}/primitives/$serve.ts +0 -0
- /package/src/{server-static → server/static}/providers/ServerStaticProvider.ts +0 -0
- /package/src/{server-swagger → server/swagger}/index.ts +0 -0
- /package/src/{server-swagger → server/swagger}/primitives/$swagger.ts +0 -0
- /package/src/topic/{errors → core/errors}/TopicTimeoutError.ts +0 -0
- /package/src/topic/{index.ts → core/index.ts} +0 -0
- /package/src/topic/{primitives → core/primitives}/$subscriber.ts +0 -0
- /package/src/topic/{primitives → core/primitives}/$topic.ts +0 -0
- /package/src/topic/{providers → core/providers}/MemoryTopicProvider.ts +0 -0
- /package/src/topic/{providers → core/providers}/TopicProvider.ts +0 -0
- /package/src/{topic-redis → topic/redis}/index.ts +0 -0
- /package/src/{topic-redis → topic/redis}/providers/RedisTopicProvider.ts +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { $env, $hook, $inject, AlephaError, t } from "alepha";
|
|
2
|
+
import { $logger } from "alepha/logger";
|
|
3
|
+
import type { DrizzleD1Database } from "drizzle-orm/d1";
|
|
4
|
+
import type { PgDatabase } from "drizzle-orm/pg-core";
|
|
5
|
+
import { SqliteModelBuilder } from "../../services/SqliteModelBuilder.ts";
|
|
6
|
+
import { DrizzleKitProvider } from "../DrizzleKitProvider.ts";
|
|
7
|
+
import { DatabaseProvider, type SQLLike } from "./DatabaseProvider.ts";
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* D1Database interface matching Cloudflare's D1 API.
|
|
13
|
+
*/
|
|
14
|
+
export interface D1Database {
|
|
15
|
+
prepare(query: string): D1PreparedStatement;
|
|
16
|
+
batch<T = unknown>(statements: D1PreparedStatement[]): Promise<T[]>;
|
|
17
|
+
exec(query: string): Promise<D1ExecResult>;
|
|
18
|
+
dump(): Promise<ArrayBuffer>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface D1PreparedStatement {
|
|
22
|
+
bind(...values: unknown[]): D1PreparedStatement;
|
|
23
|
+
first<T = unknown>(colName?: string): Promise<T | null>;
|
|
24
|
+
run(): Promise<D1Result>;
|
|
25
|
+
all<T = unknown>(): Promise<D1Result<T>>;
|
|
26
|
+
raw<T = unknown>(): Promise<T[]>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface D1Result<T = unknown> {
|
|
30
|
+
results: T[];
|
|
31
|
+
success: boolean;
|
|
32
|
+
meta: {
|
|
33
|
+
duration: number;
|
|
34
|
+
changes: number;
|
|
35
|
+
last_row_id: number;
|
|
36
|
+
served_by: string;
|
|
37
|
+
internal_stats: unknown;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface D1ExecResult {
|
|
42
|
+
count: number;
|
|
43
|
+
duration: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Cloudflare D1 SQLite provider using Drizzle ORM.
|
|
50
|
+
*
|
|
51
|
+
* This provider requires a D1 binding to be set via `cloudflareD1Options` before starting.
|
|
52
|
+
* The binding is typically obtained from the Cloudflare Workers environment.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* // In your Cloudflare Worker
|
|
57
|
+
* alepha.set(cloudflareD1Options, { binding: env.DB });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export class CloudflareD1Provider extends DatabaseProvider {
|
|
61
|
+
protected readonly kit = $inject(DrizzleKitProvider);
|
|
62
|
+
protected readonly log = $logger();
|
|
63
|
+
protected readonly builder = $inject(SqliteModelBuilder);
|
|
64
|
+
protected readonly env = $env(
|
|
65
|
+
t.object({
|
|
66
|
+
DATABASE_URL: t.string({
|
|
67
|
+
description: "Expect to be 'cloudflare-d1://name:id'",
|
|
68
|
+
}),
|
|
69
|
+
}),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
protected d1?: D1Database;
|
|
73
|
+
protected drizzleDb?: DrizzleD1Database;
|
|
74
|
+
|
|
75
|
+
public get name() {
|
|
76
|
+
return "d1";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public override readonly dialect = "sqlite";
|
|
80
|
+
|
|
81
|
+
public override get url(): string {
|
|
82
|
+
return this.env.DATABASE_URL;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public override get db(): PgDatabase<any> {
|
|
86
|
+
if (!this.drizzleDb) {
|
|
87
|
+
throw new AlephaError("D1 database not initialized");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return this.drizzleDb as unknown as PgDatabase<any>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public override async execute(
|
|
94
|
+
query: SQLLike,
|
|
95
|
+
): Promise<Array<Record<string, unknown>>> {
|
|
96
|
+
const { rows } = await (this.db as any).run(query);
|
|
97
|
+
return rows;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
protected readonly onStart = $hook({
|
|
101
|
+
on: "start",
|
|
102
|
+
handler: async () => {
|
|
103
|
+
const [bindingName] = this.env.DATABASE_URL.replace(
|
|
104
|
+
"cloudflare-d1://",
|
|
105
|
+
"",
|
|
106
|
+
).split(":");
|
|
107
|
+
const cloudflareEnv = this.alepha.store.get("cloudflare.env" as any);
|
|
108
|
+
if (!cloudflareEnv) {
|
|
109
|
+
throw new AlephaError(
|
|
110
|
+
"Cloudflare Workers environment not found in Alepha store under 'cloudflare.env'.",
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const binding = cloudflareEnv[bindingName] as D1Database;
|
|
115
|
+
if (!binding) {
|
|
116
|
+
throw new AlephaError(
|
|
117
|
+
`D1 binding '${bindingName}' not found in Cloudflare Workers environment.`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.d1 = binding;
|
|
122
|
+
|
|
123
|
+
// Dynamic import to avoid crashes when not on Cloudflare
|
|
124
|
+
const { drizzle } = await import("drizzle-orm/d1");
|
|
125
|
+
|
|
126
|
+
this.drizzleDb = drizzle(this.d1) as DrizzleD1Database;
|
|
127
|
+
|
|
128
|
+
await this.migrateDatabase();
|
|
129
|
+
|
|
130
|
+
this.log.info("Using Cloudflare D1 database");
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
protected async executeMigrations(migrationsFolder: string): Promise<void> {
|
|
135
|
+
// Dynamic import for D1 migrator
|
|
136
|
+
const { migrate } = await import("drizzle-orm/d1/migrator");
|
|
137
|
+
await migrate(this.db as any, { migrationsFolder });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Override development migration to skip sync (not supported on D1).
|
|
142
|
+
* D1 requires proper migrations to be applied.
|
|
143
|
+
*/
|
|
144
|
+
protected override async runDevelopmentMigration(
|
|
145
|
+
migrationsFolder: string,
|
|
146
|
+
): Promise<void> {
|
|
147
|
+
await this.executeMigrations(migrationsFolder);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Override test migration to run migrations instead of sync.
|
|
152
|
+
* D1 doesn't support schema synchronization.
|
|
153
|
+
*/
|
|
154
|
+
protected override async runTestMigration(): Promise<void> {
|
|
155
|
+
const migrationsFolder = this.getMigrationsFolder();
|
|
156
|
+
try {
|
|
157
|
+
await this.executeMigrations(migrationsFolder);
|
|
158
|
+
} catch {
|
|
159
|
+
this.log.warn(
|
|
160
|
+
"D1 migrations failed in test environment - ensure migrations exist",
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -145,7 +145,9 @@ export class NodeSqliteProvider extends DatabaseProvider {
|
|
|
145
145
|
on: "start",
|
|
146
146
|
handler: async () => {
|
|
147
147
|
const { DatabaseSync } = await import("node:sqlite");
|
|
148
|
-
|
|
148
|
+
|
|
149
|
+
const filepath = this.url.replace("sqlite://", "").replace("sqlite:", "");
|
|
150
|
+
|
|
149
151
|
if (filepath !== ":memory:" && filepath !== "") {
|
|
150
152
|
const dirname = filepath.split("/").slice(0, -1).join("/");
|
|
151
153
|
if (dirname) {
|
|
@@ -7,7 +7,6 @@ import { WorkerProvider } from "./providers/WorkerProvider.ts";
|
|
|
7
7
|
|
|
8
8
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
9
9
|
|
|
10
|
-
export * from "./interfaces/QueueJob.ts";
|
|
11
10
|
export * from "./primitives/$consumer.ts";
|
|
12
11
|
export * from "./primitives/$queue.ts";
|
|
13
12
|
export * from "./providers/MemoryQueueProvider.ts";
|
|
@@ -17,9 +16,9 @@ export * from "./providers/WorkerProvider.ts";
|
|
|
17
16
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
|
-
* Provides asynchronous message queuing and processing capabilities through declarative queue
|
|
19
|
+
* Provides asynchronous message queuing and processing capabilities through declarative queue descriptors.
|
|
21
20
|
*
|
|
22
|
-
* The queue module enables reliable background job processing and message passing using the `$queue`
|
|
21
|
+
* The queue module enables reliable background job processing and message passing using the `$queue` descriptor
|
|
23
22
|
* on class properties. It supports schema validation, automatic retries, and multiple queue backends for
|
|
24
23
|
* building scalable, decoupled applications with robust error handling.
|
|
25
24
|
*
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
$inject,
|
|
2
3
|
createPrimitive,
|
|
3
4
|
KIND,
|
|
4
5
|
Primitive,
|
|
@@ -7,12 +8,9 @@ import {
|
|
|
7
8
|
type TSchema,
|
|
8
9
|
} from "alepha";
|
|
9
10
|
import { $logger } from "alepha/logger";
|
|
10
|
-
import type {
|
|
11
|
-
QueueAddJobOptions,
|
|
12
|
-
QueueJobBackoff,
|
|
13
|
-
} from "../interfaces/QueueJob.ts";
|
|
14
11
|
import { MemoryQueueProvider } from "../providers/MemoryQueueProvider.ts";
|
|
15
12
|
import { QueueProvider } from "../providers/QueueProvider.ts";
|
|
13
|
+
import { WorkerProvider } from "../providers/WorkerProvider.ts";
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
* Creates a queue primitive for asynchronous message processing with background workers.
|
|
@@ -256,83 +254,6 @@ export interface QueuePrimitiveOptions<T extends TSchema> {
|
|
|
256
254
|
* ```
|
|
257
255
|
*/
|
|
258
256
|
handler?: (message: QueueMessage<T>) => Promise<void>;
|
|
259
|
-
|
|
260
|
-
// ===========================================
|
|
261
|
-
// Job Options (for crash recovery and retries)
|
|
262
|
-
// ===========================================
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Maximum number of processing attempts before the job is marked as failed.
|
|
266
|
-
* Includes the initial attempt.
|
|
267
|
-
*
|
|
268
|
-
* Set this to enable automatic retries on failure.
|
|
269
|
-
*
|
|
270
|
-
* @default 1 (no retries)
|
|
271
|
-
* @example 3 // Allows 2 retries after initial failure
|
|
272
|
-
*/
|
|
273
|
-
maxAttempts?: number;
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Backoff configuration for retries.
|
|
277
|
-
* Controls the delay between retry attempts.
|
|
278
|
-
*
|
|
279
|
-
* @example
|
|
280
|
-
* ```ts
|
|
281
|
-
* backoff: {
|
|
282
|
-
* type: "exponential",
|
|
283
|
-
* delay: 1000, // Initial delay: 1 second
|
|
284
|
-
* maxDelay: 60000 // Maximum delay: 1 minute
|
|
285
|
-
* }
|
|
286
|
-
* ```
|
|
287
|
-
*/
|
|
288
|
-
backoff?: QueueJobBackoff;
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Maximum time in milliseconds a job can be processed before it's considered stalled.
|
|
292
|
-
* If the worker doesn't complete or extend the lock within this time, the job
|
|
293
|
-
* can be picked up by another worker.
|
|
294
|
-
*
|
|
295
|
-
* Increase this for long-running jobs.
|
|
296
|
-
*
|
|
297
|
-
* @default 30000 (30 seconds)
|
|
298
|
-
*/
|
|
299
|
-
lockDuration?: number;
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Automatically remove jobs when they complete successfully.
|
|
303
|
-
* - `true`: Remove immediately after completion
|
|
304
|
-
* - `false`: Keep in completed list (default)
|
|
305
|
-
* - `number`: Keep this many most recent completed jobs, remove older ones
|
|
306
|
-
*
|
|
307
|
-
* @default false
|
|
308
|
-
* @example
|
|
309
|
-
* ```ts
|
|
310
|
-
* // Remove immediately after completion
|
|
311
|
-
* removeOnComplete: true
|
|
312
|
-
*
|
|
313
|
-
* // Keep only the last 100 completed jobs
|
|
314
|
-
* removeOnComplete: 100
|
|
315
|
-
* ```
|
|
316
|
-
*/
|
|
317
|
-
removeOnComplete?: boolean | number;
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Automatically remove jobs when they fail permanently (after all retries exhausted).
|
|
321
|
-
* - `true`: Remove immediately after failure
|
|
322
|
-
* - `false`: Keep in failed list (default)
|
|
323
|
-
* - `number`: Keep this many most recent failed jobs, remove older ones
|
|
324
|
-
*
|
|
325
|
-
* @default false
|
|
326
|
-
* @example
|
|
327
|
-
* ```ts
|
|
328
|
-
* // Remove immediately after failure
|
|
329
|
-
* removeOnFail: true
|
|
330
|
-
*
|
|
331
|
-
* // Keep only the last 50 failed jobs for debugging
|
|
332
|
-
* removeOnFail: 50
|
|
333
|
-
* ```
|
|
334
|
-
*/
|
|
335
|
-
removeOnFail?: boolean | number;
|
|
336
257
|
}
|
|
337
258
|
|
|
338
259
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
@@ -341,90 +262,24 @@ export class QueuePrimitive<T extends TSchema> extends Primitive<
|
|
|
341
262
|
QueuePrimitiveOptions<T>
|
|
342
263
|
> {
|
|
343
264
|
protected readonly log = $logger();
|
|
265
|
+
protected readonly workerProvider = $inject(WorkerProvider);
|
|
344
266
|
public readonly provider = this.$provider();
|
|
345
267
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
* @param payload - The payload to queue
|
|
359
|
-
* @param options - Job options (priority, delay)
|
|
360
|
-
*/
|
|
361
|
-
public async push(
|
|
362
|
-
payload: Static<T>,
|
|
363
|
-
options: QueueAddJobOptions,
|
|
364
|
-
): Promise<void>;
|
|
365
|
-
|
|
366
|
-
public async push(
|
|
367
|
-
payloadOrFirst: Static<T>,
|
|
368
|
-
optionsOrSecond?: QueueAddJobOptions | Static<T>,
|
|
369
|
-
...rest: Array<Static<T>>
|
|
370
|
-
): Promise<void> {
|
|
371
|
-
// Check if second argument is options object
|
|
372
|
-
const isOptions =
|
|
373
|
-
optionsOrSecond != null &&
|
|
374
|
-
typeof optionsOrSecond === "object" &&
|
|
375
|
-
("priority" in optionsOrSecond || "delay" in optionsOrSecond);
|
|
376
|
-
|
|
377
|
-
if (isOptions) {
|
|
378
|
-
// Single payload with options
|
|
379
|
-
const payload = this.alepha.codec.decode(
|
|
380
|
-
this.options.schema,
|
|
381
|
-
payloadOrFirst,
|
|
382
|
-
);
|
|
383
|
-
await this.provider.addJob(this.name, payload, {
|
|
384
|
-
...this.getDefaultJobOptions(),
|
|
385
|
-
priority: (optionsOrSecond as QueueAddJobOptions).priority,
|
|
386
|
-
delay: (optionsOrSecond as QueueAddJobOptions).delay,
|
|
387
|
-
});
|
|
388
|
-
this.log.debug(`Pushed job to queue ${this.name}`, {
|
|
389
|
-
payload,
|
|
390
|
-
options: optionsOrSecond,
|
|
391
|
-
});
|
|
392
|
-
} else {
|
|
393
|
-
// Multiple payloads without per-job options
|
|
394
|
-
const payloads =
|
|
395
|
-
optionsOrSecond != null
|
|
396
|
-
? [payloadOrFirst, optionsOrSecond as Static<T>, ...rest]
|
|
397
|
-
: [payloadOrFirst, ...rest];
|
|
268
|
+
public async push(...payloads: Array<Static<T>>) {
|
|
269
|
+
await Promise.all(
|
|
270
|
+
payloads.map((payload) =>
|
|
271
|
+
this.provider.push(
|
|
272
|
+
this.name,
|
|
273
|
+
JSON.stringify({
|
|
274
|
+
headers: {},
|
|
275
|
+
payload: this.alepha.codec.decode(this.options.schema, payload),
|
|
276
|
+
}),
|
|
277
|
+
),
|
|
278
|
+
),
|
|
279
|
+
);
|
|
398
280
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
const payload = this.alepha.codec.decode(this.options.schema, p);
|
|
402
|
-
return this.provider.addJob(
|
|
403
|
-
this.name,
|
|
404
|
-
payload,
|
|
405
|
-
this.getDefaultJobOptions(),
|
|
406
|
-
);
|
|
407
|
-
}),
|
|
408
|
-
);
|
|
409
|
-
|
|
410
|
-
this.log.debug(
|
|
411
|
-
`Pushed ${payloads.length} job(s) to queue ${this.name}`,
|
|
412
|
-
payloads,
|
|
413
|
-
);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* Get default job options from primitive configuration.
|
|
419
|
-
*/
|
|
420
|
-
protected getDefaultJobOptions() {
|
|
421
|
-
return {
|
|
422
|
-
maxAttempts: this.options.maxAttempts,
|
|
423
|
-
backoff: this.options.backoff,
|
|
424
|
-
lockDuration: this.options.lockDuration,
|
|
425
|
-
removeOnComplete: this.options.removeOnComplete,
|
|
426
|
-
removeOnFail: this.options.removeOnFail,
|
|
427
|
-
};
|
|
281
|
+
this.log.debug(`Pushed to queue ${this.name}`, payloads);
|
|
282
|
+
this.workerProvider.wakeUp();
|
|
428
283
|
}
|
|
429
284
|
|
|
430
285
|
public get name() {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { $logger } from "alepha/logger";
|
|
2
|
+
import type { QueueProvider } from "./QueueProvider.ts";
|
|
3
|
+
|
|
4
|
+
export class MemoryQueueProvider implements QueueProvider {
|
|
5
|
+
protected readonly log = $logger();
|
|
6
|
+
protected queueList: Record<string, string[]> = {};
|
|
7
|
+
|
|
8
|
+
public async push(queue: string, ...messages: string[]): Promise<void> {
|
|
9
|
+
if (this.queueList[queue] == null) {
|
|
10
|
+
this.queueList[queue] = [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
this.queueList[queue].push(...messages);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async pop(queue: string): Promise<string | undefined> {
|
|
17
|
+
return this.queueList[queue]?.shift();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimalist Queue interface.
|
|
3
|
+
*
|
|
4
|
+
* Will be probably enhanced in the future to support more advanced features. But for now, it's enough!
|
|
5
|
+
*/
|
|
6
|
+
export abstract class QueueProvider {
|
|
7
|
+
/**
|
|
8
|
+
* Push a message to the queue.
|
|
9
|
+
*
|
|
10
|
+
* @param queue Name of the queue to push the message to.
|
|
11
|
+
* @param message String message to be pushed to the queue. Buffer messages are not supported for now.
|
|
12
|
+
*/
|
|
13
|
+
public abstract push(queue: string, message: string): Promise<void>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Pop a message from the queue.
|
|
17
|
+
*
|
|
18
|
+
* @param queue Name of the queue to pop the message from.
|
|
19
|
+
*
|
|
20
|
+
* @returns The message popped or `undefined` if the queue is empty.
|
|
21
|
+
*/
|
|
22
|
+
public abstract pop(queue: string): Promise<string | undefined>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import {
|
|
2
|
+
$env,
|
|
3
|
+
$hook,
|
|
4
|
+
$inject,
|
|
5
|
+
Alepha,
|
|
6
|
+
type Static,
|
|
7
|
+
type TSchema,
|
|
8
|
+
t,
|
|
9
|
+
} from "alepha";
|
|
10
|
+
import { DateTimeProvider } from "alepha/datetime";
|
|
11
|
+
import { $logger } from "alepha/logger";
|
|
12
|
+
import { $consumer } from "../primitives/$consumer.ts";
|
|
13
|
+
import {
|
|
14
|
+
$queue,
|
|
15
|
+
type QueueMessage,
|
|
16
|
+
type QueuePrimitive,
|
|
17
|
+
} from "../primitives/$queue.ts";
|
|
18
|
+
import { QueueProvider } from "./QueueProvider.ts";
|
|
19
|
+
|
|
20
|
+
const envSchema = t.object({
|
|
21
|
+
/**
|
|
22
|
+
* The interval in milliseconds to wait before checking for new messages.
|
|
23
|
+
*/
|
|
24
|
+
QUEUE_WORKER_INTERVAL: t.integer({
|
|
25
|
+
default: 1000,
|
|
26
|
+
}),
|
|
27
|
+
/**
|
|
28
|
+
* The maximum interval in milliseconds to wait before checking for new messages.
|
|
29
|
+
*/
|
|
30
|
+
QUEUE_WORKER_MAX_INTERVAL: t.integer({
|
|
31
|
+
default: 32000,
|
|
32
|
+
}),
|
|
33
|
+
/**
|
|
34
|
+
* The number of workers to run concurrently. Defaults to 1.
|
|
35
|
+
* Useful only if you are doing a lot of I/O.
|
|
36
|
+
*/
|
|
37
|
+
QUEUE_WORKER_CONCURRENCY: t.integer({
|
|
38
|
+
default: 1,
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
declare module "alepha" {
|
|
43
|
+
interface Env extends Partial<Static<typeof envSchema>> {}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class WorkerProvider {
|
|
47
|
+
protected readonly log = $logger();
|
|
48
|
+
protected readonly env = $env(envSchema);
|
|
49
|
+
protected readonly alepha = $inject(Alepha);
|
|
50
|
+
protected readonly queueProvider = $inject(QueueProvider);
|
|
51
|
+
protected readonly dateTimeProvider = $inject(DateTimeProvider);
|
|
52
|
+
|
|
53
|
+
protected workerPromises: Array<Promise<void>> = [];
|
|
54
|
+
protected workersRunning = 0;
|
|
55
|
+
protected abortController = new AbortController();
|
|
56
|
+
protected workerIntervals: Record<number, number> = {};
|
|
57
|
+
protected consumers: Array<Consumer> = [];
|
|
58
|
+
|
|
59
|
+
public get isRunning(): boolean {
|
|
60
|
+
return this.workersRunning > 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
protected readonly start = $hook({
|
|
64
|
+
on: "start",
|
|
65
|
+
priority: "last",
|
|
66
|
+
handler: () => {
|
|
67
|
+
for (const queue of this.alepha.primitives($queue)) {
|
|
68
|
+
const handler = queue.options.handler;
|
|
69
|
+
if (handler) {
|
|
70
|
+
this.consumers.push({
|
|
71
|
+
handler,
|
|
72
|
+
queue,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
for (const consumer of this.alepha.primitives($consumer)) {
|
|
78
|
+
this.consumers.push(consumer.options);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (this.consumers.length > 0) {
|
|
82
|
+
this.startWorkers();
|
|
83
|
+
this.log.debug(
|
|
84
|
+
`Watching for ${this.consumers.length} queue${this.consumers.length > 1 ? "s" : ""} with ${this.env.QUEUE_WORKER_CONCURRENCY} worker${
|
|
85
|
+
this.env.QUEUE_WORKER_CONCURRENCY > 1 ? "s" : ""
|
|
86
|
+
}.`,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// -------------------------------------------------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
// Engine part - this is the part that will run the workers and process the messages
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Start the workers.
|
|
98
|
+
* This method will create an endless loop that will check for new messages!
|
|
99
|
+
*/
|
|
100
|
+
protected startWorkers(): void {
|
|
101
|
+
const workerToStart =
|
|
102
|
+
this.env.QUEUE_WORKER_CONCURRENCY - this.workersRunning;
|
|
103
|
+
|
|
104
|
+
for (let i = 0; i < workerToStart; i++) {
|
|
105
|
+
this.workersRunning += 1;
|
|
106
|
+
this.log.debug(`Starting worker n-${i}`);
|
|
107
|
+
|
|
108
|
+
const workerLoop = async () => {
|
|
109
|
+
while (this.workersRunning > 0) {
|
|
110
|
+
this.log.trace(`Worker n-${i} is checking for new messages`);
|
|
111
|
+
const next = await this.getNextMessage();
|
|
112
|
+
if (next) {
|
|
113
|
+
this.workerIntervals[i] = 0;
|
|
114
|
+
await this.processMessage(next);
|
|
115
|
+
} else {
|
|
116
|
+
await this.waitForNextMessage(i);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
this.log.info(`Worker n-${i} has stopped`);
|
|
120
|
+
// Only decrement if we're not already at 0 (shutdown case)
|
|
121
|
+
if (this.workersRunning > 0) {
|
|
122
|
+
this.workersRunning -= 1;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
this.workerPromises.push(
|
|
127
|
+
workerLoop().catch((e) => {
|
|
128
|
+
this.log.error(`Worker n-${i} has crashed`, e);
|
|
129
|
+
// Always decrement on crash, regardless of shutdown state
|
|
130
|
+
this.workersRunning -= 1;
|
|
131
|
+
}),
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
protected readonly stop = $hook({
|
|
137
|
+
on: "stop",
|
|
138
|
+
handler: async () => {
|
|
139
|
+
if (this.consumers.length > 0) {
|
|
140
|
+
await this.stopWorkers();
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Wait for the next message, where `n` is the worker number.
|
|
147
|
+
*
|
|
148
|
+
* This method will wait for a certain amount of time, increasing the wait time again if no message is found.
|
|
149
|
+
*/
|
|
150
|
+
protected async waitForNextMessage(n: number): Promise<void> {
|
|
151
|
+
const intervals = this.workerIntervals;
|
|
152
|
+
const milliseconds = intervals[n] || this.env.QUEUE_WORKER_INTERVAL;
|
|
153
|
+
|
|
154
|
+
this.log.trace(`Worker n-${n} is waiting for ${milliseconds}ms.`);
|
|
155
|
+
|
|
156
|
+
if (this.abortController.signal.aborted) {
|
|
157
|
+
this.log.warn(`Worker n-${n} aborted.`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
await this.dateTimeProvider.wait(milliseconds, {
|
|
162
|
+
signal: this.abortController.signal,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (intervals[n]) {
|
|
166
|
+
if (intervals[n] < this.env.QUEUE_WORKER_MAX_INTERVAL) {
|
|
167
|
+
intervals[n] = intervals[n] * 2;
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
intervals[n] = milliseconds;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get the next message.
|
|
176
|
+
*/
|
|
177
|
+
protected async getNextMessage(): Promise<undefined | NextMessage> {
|
|
178
|
+
for (const consumer of this.consumers) {
|
|
179
|
+
const provider = consumer.queue.provider;
|
|
180
|
+
const message = await provider.pop(consumer.queue.name);
|
|
181
|
+
if (message) {
|
|
182
|
+
return { message, consumer };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Process a message from a queue.
|
|
189
|
+
*/
|
|
190
|
+
protected async processMessage(response: {
|
|
191
|
+
message: any;
|
|
192
|
+
consumer: Consumer;
|
|
193
|
+
}) {
|
|
194
|
+
const { message, consumer } = response;
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
const json = JSON.parse(message);
|
|
198
|
+
const payload = this.alepha.codec.decode(
|
|
199
|
+
consumer.queue.options.schema,
|
|
200
|
+
json.payload,
|
|
201
|
+
);
|
|
202
|
+
await this.alepha.context.run(() => consumer.handler({ payload }));
|
|
203
|
+
} catch (e) {
|
|
204
|
+
this.log.error("Failed to process message", e);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Stop the workers.
|
|
210
|
+
*
|
|
211
|
+
* This method will stop the workers and wait for them to finish processing.
|
|
212
|
+
*/
|
|
213
|
+
protected async stopWorkers() {
|
|
214
|
+
this.workersRunning = 0;
|
|
215
|
+
|
|
216
|
+
this.log.trace("Stopping workers...");
|
|
217
|
+
this.abortController.abort();
|
|
218
|
+
|
|
219
|
+
this.log.trace("Waiting for workers to finish...");
|
|
220
|
+
await Promise.all(this.workerPromises);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Force the workers to get back to work.
|
|
225
|
+
*/
|
|
226
|
+
public wakeUp(): void {
|
|
227
|
+
this.log.debug("Waking up workers...");
|
|
228
|
+
this.abortController.abort();
|
|
229
|
+
this.abortController = new AbortController();
|
|
230
|
+
|
|
231
|
+
// if no workers are running, start them, (should not happen, but just in case)
|
|
232
|
+
this.startWorkers();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface Consumer<T extends TSchema = TSchema> {
|
|
237
|
+
queue: QueuePrimitive<T>;
|
|
238
|
+
handler: (message: QueueMessage<T>) => Promise<void>;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface NextMessage {
|
|
242
|
+
consumer: Consumer;
|
|
243
|
+
message: string;
|
|
244
|
+
}
|