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.
Files changed (512) hide show
  1. package/README.md +5 -2
  2. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  3. package/assets/swagger-ui/swagger-ui-standalone-preset.js +1 -1
  4. package/assets/swagger-ui/swagger-ui.css +1 -1
  5. package/dist/{api-audits → api/audits}/index.browser.js +4 -4
  6. package/dist/api/audits/index.browser.js.map +1 -0
  7. package/dist/{api-audits → api/audits}/index.d.ts +10 -9
  8. package/dist/api/audits/index.d.ts.map +1 -0
  9. package/dist/{api-audits → api/audits}/index.js +8 -8
  10. package/dist/api/audits/index.js.map +1 -0
  11. package/dist/{api-files → api/files}/index.browser.js +5 -5
  12. package/dist/api/files/index.browser.js.map +1 -0
  13. package/dist/{api-files → api/files}/index.d.ts +18 -10
  14. package/dist/api/files/index.d.ts.map +1 -0
  15. package/dist/{api-files → api/files}/index.js +10 -10
  16. package/dist/api/files/index.js.map +1 -0
  17. package/dist/{api-jobs → api/jobs}/index.browser.js +5 -5
  18. package/dist/api/jobs/index.browser.js.map +1 -0
  19. package/dist/{api-jobs → api/jobs}/index.d.ts +168 -167
  20. package/dist/api/jobs/index.d.ts.map +1 -0
  21. package/dist/{api-jobs → api/jobs}/index.js +9 -9
  22. package/dist/api/jobs/index.js.map +1 -0
  23. package/dist/{api-notifications → api/notifications}/index.browser.js +11 -11
  24. package/dist/api/notifications/index.browser.js.map +1 -0
  25. package/dist/api/notifications/index.d.ts +327 -0
  26. package/dist/api/notifications/index.d.ts.map +1 -0
  27. package/dist/{api-notifications → api/notifications}/index.js +11 -11
  28. package/dist/api/notifications/index.js.map +1 -0
  29. package/dist/{api-parameters → api/parameters}/index.browser.js +2 -2
  30. package/dist/api/parameters/index.browser.js.map +1 -0
  31. package/dist/{api-parameters → api/parameters}/index.d.ts +11 -11
  32. package/dist/api/parameters/index.d.ts.map +1 -0
  33. package/dist/{api-parameters → api/parameters}/index.js +7 -7
  34. package/dist/api/parameters/index.js.map +1 -0
  35. package/dist/{api-users → api/users}/index.browser.js +6 -6
  36. package/dist/api/users/index.browser.js.map +1 -0
  37. package/dist/{api-users → api/users}/index.d.ts +836 -836
  38. package/dist/api/users/index.d.ts.map +1 -0
  39. package/dist/{api-users → api/users}/index.js +99 -766
  40. package/dist/api/users/index.js.map +1 -0
  41. package/dist/{api-verifications → api/verifications}/index.browser.js +5 -5
  42. package/dist/api/verifications/index.browser.js.map +1 -0
  43. package/dist/api/verifications/index.d.ts +248 -0
  44. package/dist/api/verifications/index.d.ts.map +1 -0
  45. package/dist/{api-verifications → api/verifications}/index.js +11 -11
  46. package/dist/api/verifications/index.js.map +1 -0
  47. package/dist/batch/index.d.ts.map +1 -0
  48. package/dist/bucket/index.d.ts.map +1 -0
  49. package/dist/cache/{index.d.ts → core/index.d.ts} +4 -4
  50. package/dist/cache/core/index.d.ts.map +1 -0
  51. package/dist/cache/{index.js → core/index.js} +5 -5
  52. package/dist/cache/core/index.js.map +1 -0
  53. package/dist/{cache-redis → cache/redis}/index.d.ts +2 -2
  54. package/dist/cache/redis/index.d.ts.map +1 -0
  55. package/dist/{cache-redis → cache/redis}/index.js +2 -2
  56. package/dist/cache/redis/index.js.map +1 -0
  57. package/dist/cli/index.d.ts +78 -58
  58. package/dist/cli/index.d.ts.map +1 -0
  59. package/dist/cli/index.js +454 -154
  60. package/dist/cli/index.js.map +1 -1
  61. package/dist/command/index.d.ts +15 -5
  62. package/dist/command/index.d.ts.map +1 -0
  63. package/dist/command/index.js +45 -6
  64. package/dist/command/index.js.map +1 -1
  65. package/dist/core/index.browser.js +1334 -1318
  66. package/dist/core/index.browser.js.map +1 -1
  67. package/dist/core/index.d.ts +75 -71
  68. package/dist/core/index.d.ts.map +1 -0
  69. package/dist/core/index.js +1337 -1321
  70. package/dist/core/index.js.map +1 -1
  71. package/dist/core/index.native.js +1337 -1321
  72. package/dist/core/index.native.js.map +1 -1
  73. package/dist/datetime/index.d.ts.map +1 -0
  74. package/dist/email/index.d.ts.map +1 -0
  75. package/dist/fake/index.d.ts.map +1 -0
  76. package/dist/file/index.d.ts.map +1 -0
  77. package/dist/lock/{index.d.ts → core/index.d.ts} +5 -5
  78. package/dist/lock/core/index.d.ts.map +1 -0
  79. package/dist/lock/{index.js → core/index.js} +5 -5
  80. package/dist/lock/core/index.js.map +1 -0
  81. package/dist/{lock-redis → lock/redis}/index.d.ts +2 -2
  82. package/dist/lock/redis/index.d.ts.map +1 -0
  83. package/dist/{lock-redis → lock/redis}/index.js +2 -2
  84. package/dist/lock/redis/index.js.map +1 -0
  85. package/dist/logger/index.d.ts +1 -0
  86. package/dist/logger/index.d.ts.map +1 -0
  87. package/dist/mcp/index.d.ts +820 -0
  88. package/dist/mcp/index.d.ts.map +1 -0
  89. package/dist/mcp/index.js +978 -0
  90. package/dist/mcp/index.js.map +1 -0
  91. package/dist/orm/index.d.ts +180 -107
  92. package/dist/orm/index.d.ts.map +1 -0
  93. package/dist/orm/index.js +260 -174
  94. package/dist/orm/index.js.map +1 -1
  95. package/dist/queue/core/index.d.ts +548 -0
  96. package/dist/queue/core/index.d.ts.map +1 -0
  97. package/dist/queue/core/index.js +391 -0
  98. package/dist/queue/core/index.js.map +1 -0
  99. package/dist/queue/redis/index.d.ts +28 -0
  100. package/dist/queue/redis/index.d.ts.map +1 -0
  101. package/dist/queue/redis/index.js +43 -0
  102. package/dist/queue/redis/index.js.map +1 -0
  103. package/dist/redis/index.d.ts.map +1 -0
  104. package/dist/retry/index.d.ts.map +1 -0
  105. package/dist/router/index.d.ts.map +1 -0
  106. package/dist/scheduler/index.d.ts +1 -1
  107. package/dist/scheduler/index.d.ts.map +1 -0
  108. package/dist/scheduler/index.js +1 -393
  109. package/dist/scheduler/index.js.map +1 -1
  110. package/dist/security/index.d.ts +1 -1
  111. package/dist/security/index.d.ts.map +1 -0
  112. package/dist/security/index.js +2 -1413
  113. package/dist/security/index.js.map +1 -1
  114. package/dist/{server-auth → server/auth}/index.browser.js +6 -6
  115. package/dist/server/auth/index.browser.js.map +1 -0
  116. package/dist/{server-auth → server/auth}/index.d.ts +167 -167
  117. package/dist/server/auth/index.d.ts.map +1 -0
  118. package/dist/server/auth/index.js +742 -0
  119. package/dist/server/auth/index.js.map +1 -0
  120. package/dist/{server-cache → server/cache}/index.d.ts +2 -2
  121. package/dist/server/cache/index.d.ts.map +1 -0
  122. package/dist/{server-cache → server/cache}/index.js +2 -2
  123. package/dist/server/cache/index.js.map +1 -0
  124. package/dist/{server-compress → server/compress}/index.d.ts +2 -2
  125. package/dist/server/compress/index.d.ts.map +1 -0
  126. package/dist/{server-compress → server/compress}/index.js +2 -2
  127. package/dist/server/compress/index.js.map +1 -0
  128. package/dist/{server-cookies → server/cookies}/index.browser.js +3 -3
  129. package/dist/server/cookies/index.browser.js.map +1 -0
  130. package/dist/{server-cookies → server/cookies}/index.d.ts +4 -4
  131. package/dist/server/cookies/index.d.ts.map +1 -0
  132. package/dist/{server-cookies → server/cookies}/index.js +4 -4
  133. package/dist/server/cookies/index.js.map +1 -0
  134. package/dist/server/{index.browser.js → core/index.browser.js} +14 -14
  135. package/dist/server/core/index.browser.js.map +1 -0
  136. package/dist/server/{index.d.ts → core/index.d.ts} +36 -36
  137. package/dist/server/core/index.d.ts.map +1 -0
  138. package/dist/server/{index.js → core/index.js} +27 -27
  139. package/dist/server/core/index.js.map +1 -0
  140. package/dist/{server-cors → server/cors}/index.d.ts +3 -3
  141. package/dist/server/cors/index.d.ts.map +1 -0
  142. package/dist/{server-cors → server/cors}/index.js +3 -3
  143. package/dist/server/cors/index.js.map +1 -0
  144. package/dist/{server-health → server/health}/index.d.ts +3 -3
  145. package/dist/server/health/index.d.ts.map +1 -0
  146. package/dist/{server-health → server/health}/index.js +3 -3
  147. package/dist/server/health/index.js.map +1 -0
  148. package/dist/{server-helmet → server/helmet}/index.d.ts +2 -2
  149. package/dist/server/helmet/index.d.ts.map +1 -0
  150. package/dist/{server-helmet → server/helmet}/index.js +2 -2
  151. package/dist/server/helmet/index.js.map +1 -0
  152. package/dist/{server-links → server/links}/index.browser.js +5 -5
  153. package/dist/server/links/index.browser.js.map +1 -0
  154. package/dist/{server-links → server/links}/index.d.ts +40 -40
  155. package/dist/server/links/index.d.ts.map +1 -0
  156. package/dist/{server-links → server/links}/index.js +7 -7
  157. package/dist/server/links/index.js.map +1 -0
  158. package/dist/{server-metrics → server/metrics}/index.d.ts +2 -2
  159. package/dist/server/metrics/index.d.ts.map +1 -0
  160. package/dist/server/metrics/index.js +74 -0
  161. package/dist/server/metrics/index.js.map +1 -0
  162. package/dist/{server-multipart → server/multipart}/index.d.ts +2 -2
  163. package/dist/server/multipart/index.d.ts.map +1 -0
  164. package/dist/{server-multipart → server/multipart}/index.js +2 -2
  165. package/dist/server/multipart/index.js.map +1 -0
  166. package/dist/{server-proxy → server/proxy}/index.d.ts +3 -3
  167. package/dist/server/proxy/index.d.ts.map +1 -0
  168. package/dist/{server-proxy → server/proxy}/index.js +3 -3
  169. package/dist/server/proxy/index.js.map +1 -0
  170. package/dist/{server-rate-limit → server/rate-limit}/index.d.ts +4 -4
  171. package/dist/server/rate-limit/index.d.ts.map +1 -0
  172. package/dist/{server-rate-limit → server/rate-limit}/index.js +4 -4
  173. package/dist/server/rate-limit/index.js.map +1 -0
  174. package/dist/{server-security → server/security}/index.browser.js +1 -1
  175. package/dist/server/security/index.browser.js.map +1 -0
  176. package/dist/{server-security → server/security}/index.d.ts +4 -4
  177. package/dist/server/security/index.d.ts.map +1 -0
  178. package/dist/{server-security → server/security}/index.js +4 -4
  179. package/dist/server/security/index.js.map +1 -0
  180. package/dist/{server-static → server/static}/index.d.ts +3 -3
  181. package/dist/server/static/index.d.ts.map +1 -0
  182. package/dist/{server-static → server/static}/index.js +3 -3
  183. package/dist/server/static/index.js.map +1 -0
  184. package/dist/{server-swagger → server/swagger}/index.d.ts +3 -3
  185. package/dist/server/swagger/index.d.ts.map +1 -0
  186. package/dist/{server-swagger → server/swagger}/index.js +4 -4
  187. package/dist/server/swagger/index.js.map +1 -0
  188. package/dist/sms/index.d.ts.map +1 -0
  189. package/dist/thread/index.d.ts.map +1 -0
  190. package/dist/topic/{index.d.ts → core/index.d.ts} +6 -6
  191. package/dist/topic/core/index.d.ts.map +1 -0
  192. package/dist/topic/{index.js → core/index.js} +6 -6
  193. package/dist/topic/core/index.js.map +1 -0
  194. package/dist/{topic-redis → topic/redis}/index.d.ts +2 -2
  195. package/dist/topic/redis/index.d.ts.map +1 -0
  196. package/dist/{topic-redis → topic/redis}/index.js +2 -2
  197. package/dist/topic/redis/index.js.map +1 -0
  198. package/dist/vite/index.d.ts +21 -2
  199. package/dist/vite/index.d.ts.map +1 -0
  200. package/dist/vite/index.js +48 -19
  201. package/dist/vite/index.js.map +1 -1
  202. package/dist/websocket/index.d.ts.map +1 -0
  203. package/package.json +162 -158
  204. package/src/{api-files → api/files}/index.ts +1 -0
  205. package/src/{api-parameters → api/parameters}/index.ts +1 -1
  206. package/src/{api-users → api/users}/primitives/$userRealm.ts +1 -1
  207. package/src/{api-users → api/users}/providers/UserRealmProvider.ts +6 -7
  208. package/src/{api-verifications → api/verifications}/index.ts +2 -0
  209. package/src/cli/apps/AlephaCli.ts +2 -0
  210. package/src/cli/apps/AlephaPackageBuilderCli.ts +83 -54
  211. package/src/cli/assets/appRouterTs.ts +1 -1
  212. package/src/cli/assets/biomeJson.ts +1 -1
  213. package/src/cli/assets/indexHtml.ts +1 -1
  214. package/src/cli/assets/mainBrowserTs.ts +1 -1
  215. package/src/cli/assets/mainTs.ts +9 -10
  216. package/src/cli/assets/viteConfigTs.ts +1 -1
  217. package/src/cli/commands/ChangelogCommands.ts +389 -0
  218. package/src/cli/commands/CoreCommands.ts +10 -6
  219. package/src/cli/commands/DrizzleCommands.ts +204 -4
  220. package/src/cli/commands/VerifyCommands.ts +4 -1
  221. package/src/cli/commands/ViteCommands.ts +46 -25
  222. package/src/cli/services/AlephaCliUtils.ts +52 -164
  223. package/src/command/providers/CliProvider.ts +76 -5
  224. package/src/core/providers/SchemaValidator.ts +24 -2
  225. package/src/mcp/errors/McpError.ts +72 -0
  226. package/src/mcp/helpers/jsonrpc.ts +163 -0
  227. package/src/mcp/index.ts +132 -0
  228. package/src/mcp/interfaces/McpTypes.ts +248 -0
  229. package/src/mcp/primitives/$prompt.ts +188 -0
  230. package/src/mcp/primitives/$resource.ts +171 -0
  231. package/src/mcp/primitives/$tool.ts +285 -0
  232. package/src/mcp/providers/McpServerProvider.ts +382 -0
  233. package/src/mcp/transports/SseMcpTransport.ts +172 -0
  234. package/src/mcp/transports/StdioMcpTransport.ts +126 -0
  235. package/src/orm/index.ts +12 -0
  236. package/src/orm/providers/drivers/CloudflareD1Provider.ts +164 -0
  237. package/src/orm/providers/drivers/NodeSqliteProvider.ts +3 -1
  238. package/src/queue/{index.ts → core/index.ts} +2 -3
  239. package/src/queue/{primitives → core/primitives}/$queue.ts +17 -162
  240. package/src/queue/core/providers/MemoryQueueProvider.ts +19 -0
  241. package/src/queue/core/providers/QueueProvider.ts +23 -0
  242. package/src/queue/core/providers/WorkerProvider.ts +244 -0
  243. package/src/queue/redis/providers/RedisQueueProvider.ts +31 -0
  244. package/src/server/{index.ts → core/index.ts} +1 -0
  245. package/src/{server-rate-limit → server/rate-limit}/index.ts +1 -1
  246. package/src/{server-swagger → server/swagger}/providers/ServerSwaggerProvider.ts +1 -0
  247. package/src/vite/plugins/viteAlephaBuild.ts +8 -2
  248. package/src/vite/plugins/viteAlephaDev.ts +6 -2
  249. package/src/vite/tasks/buildServer.ts +1 -1
  250. package/src/vite/tasks/copyAssets.ts +32 -8
  251. package/src/vite/tasks/generateCloudflare.ts +43 -15
  252. package/src/vite/tasks/runAlepha.ts +1 -0
  253. package/dist/api-audits/index.browser.js.map +0 -1
  254. package/dist/api-audits/index.js.map +0 -1
  255. package/dist/api-files/index.browser.js.map +0 -1
  256. package/dist/api-files/index.js.map +0 -1
  257. package/dist/api-jobs/index.browser.js.map +0 -1
  258. package/dist/api-jobs/index.js.map +0 -1
  259. package/dist/api-notifications/index.browser.js.map +0 -1
  260. package/dist/api-notifications/index.d.ts +0 -327
  261. package/dist/api-notifications/index.js.map +0 -1
  262. package/dist/api-parameters/index.browser.js.map +0 -1
  263. package/dist/api-parameters/index.js.map +0 -1
  264. package/dist/api-users/index.browser.js.map +0 -1
  265. package/dist/api-users/index.js.map +0 -1
  266. package/dist/api-verifications/index.browser.js.map +0 -1
  267. package/dist/api-verifications/index.d.ts +0 -229
  268. package/dist/api-verifications/index.js.map +0 -1
  269. package/dist/cache/index.js.map +0 -1
  270. package/dist/cache-redis/index.js.map +0 -1
  271. package/dist/lock/index.js.map +0 -1
  272. package/dist/lock-redis/index.js.map +0 -1
  273. package/dist/queue/index.d.ts +0 -1265
  274. package/dist/queue/index.js +0 -1037
  275. package/dist/queue/index.js.map +0 -1
  276. package/dist/queue-redis/index.d.ts +0 -82
  277. package/dist/queue-redis/index.js +0 -872
  278. package/dist/queue-redis/index.js.map +0 -1
  279. package/dist/server/index.browser.js.map +0 -1
  280. package/dist/server/index.js.map +0 -1
  281. package/dist/server-auth/index.browser.js.map +0 -1
  282. package/dist/server-auth/index.js +0 -1973
  283. package/dist/server-auth/index.js.map +0 -1
  284. package/dist/server-cache/index.js.map +0 -1
  285. package/dist/server-compress/index.js.map +0 -1
  286. package/dist/server-cookies/index.browser.js.map +0 -1
  287. package/dist/server-cookies/index.js.map +0 -1
  288. package/dist/server-cors/index.js.map +0 -1
  289. package/dist/server-health/index.js.map +0 -1
  290. package/dist/server-helmet/index.js.map +0 -1
  291. package/dist/server-links/index.browser.js.map +0 -1
  292. package/dist/server-links/index.js.map +0 -1
  293. package/dist/server-metrics/index.js +0 -4532
  294. package/dist/server-metrics/index.js.map +0 -1
  295. package/dist/server-multipart/index.js.map +0 -1
  296. package/dist/server-proxy/index.js.map +0 -1
  297. package/dist/server-rate-limit/index.js.map +0 -1
  298. package/dist/server-security/index.browser.js.map +0 -1
  299. package/dist/server-security/index.js.map +0 -1
  300. package/dist/server-static/index.js.map +0 -1
  301. package/dist/server-swagger/index.js.map +0 -1
  302. package/dist/topic/index.js.map +0 -1
  303. package/dist/topic-redis/index.js.map +0 -1
  304. package/src/queue/interfaces/QueueJob.ts +0 -459
  305. package/src/queue/providers/MemoryQueueProvider.ts +0 -850
  306. package/src/queue/providers/QueueProvider.ts +0 -319
  307. package/src/queue/providers/WorkerProvider.ts +0 -344
  308. package/src/queue-redis/providers/RedisQueueProvider.ts +0 -1209
  309. /package/src/{api-audits → api/audits}/controllers/AuditController.ts +0 -0
  310. /package/src/{api-audits → api/audits}/entities/audits.ts +0 -0
  311. /package/src/{api-audits → api/audits}/index.browser.ts +0 -0
  312. /package/src/{api-audits → api/audits}/index.ts +0 -0
  313. /package/src/{api-audits → api/audits}/primitives/$audit.ts +0 -0
  314. /package/src/{api-audits → api/audits}/schemas/auditQuerySchema.ts +0 -0
  315. /package/src/{api-audits → api/audits}/schemas/auditResourceSchema.ts +0 -0
  316. /package/src/{api-audits → api/audits}/schemas/createAuditSchema.ts +0 -0
  317. /package/src/{api-audits → api/audits}/services/AuditService.ts +0 -0
  318. /package/src/{api-files → api/files}/controllers/FileController.ts +0 -0
  319. /package/src/{api-files → api/files}/controllers/StorageStatsController.ts +0 -0
  320. /package/src/{api-files → api/files}/entities/files.ts +0 -0
  321. /package/src/{api-files → api/files}/index.browser.ts +0 -0
  322. /package/src/{api-files → api/files}/jobs/FileJobs.ts +0 -0
  323. /package/src/{api-files → api/files}/schemas/fileQuerySchema.ts +0 -0
  324. /package/src/{api-files → api/files}/schemas/fileResourceSchema.ts +0 -0
  325. /package/src/{api-files → api/files}/schemas/storageStatsSchema.ts +0 -0
  326. /package/src/{api-files → api/files}/services/FileService.ts +0 -0
  327. /package/src/{api-jobs → api/jobs}/controllers/JobController.ts +0 -0
  328. /package/src/{api-jobs → api/jobs}/entities/jobExecutions.ts +0 -0
  329. /package/src/{api-jobs → api/jobs}/index.browser.ts +0 -0
  330. /package/src/{api-jobs → api/jobs}/index.ts +0 -0
  331. /package/src/{api-jobs → api/jobs}/primitives/$job.ts +0 -0
  332. /package/src/{api-jobs → api/jobs}/providers/JobProvider.ts +0 -0
  333. /package/src/{api-jobs → api/jobs}/schemas/jobExecutionQuerySchema.ts +0 -0
  334. /package/src/{api-jobs → api/jobs}/schemas/jobExecutionResourceSchema.ts +0 -0
  335. /package/src/{api-jobs → api/jobs}/schemas/triggerJobSchema.ts +0 -0
  336. /package/src/{api-jobs → api/jobs}/services/JobService.ts +0 -0
  337. /package/src/{api-notifications → api/notifications}/controllers/NotificationController.ts +0 -0
  338. /package/src/{api-notifications → api/notifications}/entities/notifications.ts +0 -0
  339. /package/src/{api-notifications → api/notifications}/index.browser.ts +0 -0
  340. /package/src/{api-notifications → api/notifications}/index.ts +0 -0
  341. /package/src/{api-notifications → api/notifications}/jobs/NotificationJobs.ts +0 -0
  342. /package/src/{api-notifications → api/notifications}/primitives/$notification.ts +0 -0
  343. /package/src/{api-notifications → api/notifications}/queues/NotificationQueues.ts +0 -0
  344. /package/src/{api-notifications → api/notifications}/schemas/notificationContactPreferencesSchema.ts +0 -0
  345. /package/src/{api-notifications → api/notifications}/schemas/notificationContactSchema.ts +0 -0
  346. /package/src/{api-notifications → api/notifications}/schemas/notificationCreateSchema.ts +0 -0
  347. /package/src/{api-notifications → api/notifications}/schemas/notificationQuerySchema.ts +0 -0
  348. /package/src/{api-notifications → api/notifications}/services/NotificationSenderService.ts +0 -0
  349. /package/src/{api-notifications → api/notifications}/services/NotificationService.ts +0 -0
  350. /package/src/{api-parameters → api/parameters}/controllers/ConfigController.ts +0 -0
  351. /package/src/{api-parameters → api/parameters}/entities/parameters.ts +0 -0
  352. /package/src/{api-parameters → api/parameters}/index.browser.ts +0 -0
  353. /package/src/{api-parameters → api/parameters}/primitives/$config.ts +0 -0
  354. /package/src/{api-parameters → api/parameters}/schedulers/ConfigActivationScheduler.ts +0 -0
  355. /package/src/{api-parameters → api/parameters}/services/ConfigStore.ts +0 -0
  356. /package/src/{api-users → api/users}/atoms/realmAuthSettingsAtom.ts +0 -0
  357. /package/src/{api-users → api/users}/controllers/IdentityController.ts +0 -0
  358. /package/src/{api-users → api/users}/controllers/SessionController.ts +0 -0
  359. /package/src/{api-users → api/users}/controllers/UserController.ts +0 -0
  360. /package/src/{api-users → api/users}/controllers/UserRealmController.ts +0 -0
  361. /package/src/{api-users → api/users}/entities/identities.ts +0 -0
  362. /package/src/{api-users → api/users}/entities/sessions.ts +0 -0
  363. /package/src/{api-users → api/users}/entities/users.ts +0 -0
  364. /package/src/{api-users → api/users}/index.browser.ts +0 -0
  365. /package/src/{api-users → api/users}/index.ts +0 -0
  366. /package/src/{api-users → api/users}/notifications/UserNotifications.ts +0 -0
  367. /package/src/{api-users → api/users}/schemas/completePasswordResetRequestSchema.ts +0 -0
  368. /package/src/{api-users → api/users}/schemas/completeRegistrationRequestSchema.ts +0 -0
  369. /package/src/{api-users → api/users}/schemas/createUserSchema.ts +0 -0
  370. /package/src/{api-users → api/users}/schemas/identityQuerySchema.ts +0 -0
  371. /package/src/{api-users → api/users}/schemas/identityResourceSchema.ts +0 -0
  372. /package/src/{api-users → api/users}/schemas/loginSchema.ts +0 -0
  373. /package/src/{api-users → api/users}/schemas/passwordResetIntentResponseSchema.ts +0 -0
  374. /package/src/{api-users → api/users}/schemas/registerQuerySchema.ts +0 -0
  375. /package/src/{api-users → api/users}/schemas/registerRequestSchema.ts +0 -0
  376. /package/src/{api-users → api/users}/schemas/registerResponseSchema.ts +0 -0
  377. /package/src/{api-users → api/users}/schemas/registerSchema.ts +0 -0
  378. /package/src/{api-users → api/users}/schemas/registrationIntentResponseSchema.ts +0 -0
  379. /package/src/{api-users → api/users}/schemas/resetPasswordSchema.ts +0 -0
  380. /package/src/{api-users → api/users}/schemas/sessionQuerySchema.ts +0 -0
  381. /package/src/{api-users → api/users}/schemas/sessionResourceSchema.ts +0 -0
  382. /package/src/{api-users → api/users}/schemas/updateUserSchema.ts +0 -0
  383. /package/src/{api-users → api/users}/schemas/userQuerySchema.ts +0 -0
  384. /package/src/{api-users → api/users}/schemas/userRealmConfigSchema.ts +0 -0
  385. /package/src/{api-users → api/users}/schemas/userResourceSchema.ts +0 -0
  386. /package/src/{api-users → api/users}/services/CredentialService.ts +0 -0
  387. /package/src/{api-users → api/users}/services/IdentityService.ts +0 -0
  388. /package/src/{api-users → api/users}/services/RegistrationService.ts +0 -0
  389. /package/src/{api-users → api/users}/services/SessionCrudService.ts +0 -0
  390. /package/src/{api-users → api/users}/services/SessionService.ts +0 -0
  391. /package/src/{api-users → api/users}/services/UserService.ts +0 -0
  392. /package/src/{api-verifications → api/verifications}/controllers/VerificationController.ts +0 -0
  393. /package/src/{api-verifications → api/verifications}/entities/verifications.ts +0 -0
  394. /package/src/{api-verifications → api/verifications}/index.browser.ts +0 -0
  395. /package/src/{api-verifications → api/verifications}/jobs/VerificationJobs.ts +0 -0
  396. /package/src/{api-verifications → api/verifications}/parameters/VerificationParameters.ts +0 -0
  397. /package/src/{api-verifications → api/verifications}/schemas/requestVerificationCodeResponseSchema.ts +0 -0
  398. /package/src/{api-verifications → api/verifications}/schemas/validateVerificationCodeResponseSchema.ts +0 -0
  399. /package/src/{api-verifications → api/verifications}/schemas/verificationSettingsSchema.ts +0 -0
  400. /package/src/{api-verifications → api/verifications}/schemas/verificationTypeEnumSchema.ts +0 -0
  401. /package/src/{api-verifications → api/verifications}/services/VerificationService.ts +0 -0
  402. /package/src/cache/{errors → core/errors}/CacheError.ts +0 -0
  403. /package/src/cache/{index.ts → core/index.ts} +0 -0
  404. /package/src/cache/{primitives → core/primitives}/$cache.ts +0 -0
  405. /package/src/cache/{providers → core/providers}/CacheProvider.ts +0 -0
  406. /package/src/cache/{providers → core/providers}/MemoryCacheProvider.ts +0 -0
  407. /package/src/{cache-redis → cache/redis}/index.ts +0 -0
  408. /package/src/{cache-redis → cache/redis}/providers/RedisCacheProvider.ts +0 -0
  409. /package/src/lock/{index.ts → core/index.ts} +0 -0
  410. /package/src/lock/{primitives → core/primitives}/$lock.ts +0 -0
  411. /package/src/lock/{providers → core/providers}/LockProvider.ts +0 -0
  412. /package/src/lock/{providers → core/providers}/LockTopicProvider.ts +0 -0
  413. /package/src/lock/{providers → core/providers}/MemoryLockProvider.ts +0 -0
  414. /package/src/{lock-redis → lock/redis}/index.ts +0 -0
  415. /package/src/{lock-redis → lock/redis}/providers/RedisLockProvider.ts +0 -0
  416. /package/src/queue/{primitives → core/primitives}/$consumer.ts +0 -0
  417. /package/src/{queue-redis → queue/redis}/index.ts +0 -0
  418. /package/src/{server-auth → server/auth}/constants/routes.ts +0 -0
  419. /package/src/{server-auth → server/auth}/index.browser.ts +0 -0
  420. /package/src/{server-auth → server/auth}/index.shared.ts +0 -0
  421. /package/src/{server-auth → server/auth}/index.ts +0 -0
  422. /package/src/{server-auth → server/auth}/primitives/$auth.ts +0 -0
  423. /package/src/{server-auth → server/auth}/primitives/$authApple.ts +0 -0
  424. /package/src/{server-auth → server/auth}/primitives/$authCredentials.ts +0 -0
  425. /package/src/{server-auth → server/auth}/primitives/$authGithub.ts +0 -0
  426. /package/src/{server-auth → server/auth}/primitives/$authGoogle.ts +0 -0
  427. /package/src/{server-auth → server/auth}/providers/ServerAuthProvider.ts +0 -0
  428. /package/src/{server-auth → server/auth}/schemas/authenticationProviderSchema.ts +0 -0
  429. /package/src/{server-auth → server/auth}/schemas/tokenResponseSchema.ts +0 -0
  430. /package/src/{server-auth → server/auth}/schemas/tokensSchema.ts +0 -0
  431. /package/src/{server-auth → server/auth}/schemas/userinfoResponseSchema.ts +0 -0
  432. /package/src/{server-cache → server/cache}/index.ts +0 -0
  433. /package/src/{server-cache → server/cache}/providers/ServerCacheProvider.ts +0 -0
  434. /package/src/{server-compress → server/compress}/index.ts +0 -0
  435. /package/src/{server-compress → server/compress}/providers/ServerCompressProvider.ts +0 -0
  436. /package/src/{server-cookies → server/cookies}/index.browser.ts +0 -0
  437. /package/src/{server-cookies → server/cookies}/index.ts +0 -0
  438. /package/src/{server-cookies → server/cookies}/primitives/$cookie.browser.ts +0 -0
  439. /package/src/{server-cookies → server/cookies}/primitives/$cookie.ts +0 -0
  440. /package/src/{server-cookies → server/cookies}/providers/ServerCookiesProvider.ts +0 -0
  441. /package/src/{server-cookies → server/cookies}/services/CookieParser.ts +0 -0
  442. /package/src/server/{constants → core/constants}/routeMethods.ts +0 -0
  443. /package/src/server/{errors → core/errors}/BadRequestError.ts +0 -0
  444. /package/src/server/{errors → core/errors}/ConflictError.ts +0 -0
  445. /package/src/server/{errors → core/errors}/ForbiddenError.ts +0 -0
  446. /package/src/server/{errors → core/errors}/HttpError.ts +0 -0
  447. /package/src/server/{errors → core/errors}/NotFoundError.ts +0 -0
  448. /package/src/server/{errors → core/errors}/UnauthorizedError.ts +0 -0
  449. /package/src/server/{errors → core/errors}/ValidationError.ts +0 -0
  450. /package/src/server/{helpers → core/helpers}/ServerReply.ts +0 -0
  451. /package/src/server/{helpers → core/helpers}/isMultipart.ts +0 -0
  452. /package/src/server/{index.browser.ts → core/index.browser.ts} +0 -0
  453. /package/src/server/{index.shared.ts → core/index.shared.ts} +0 -0
  454. /package/src/server/{interfaces → core/interfaces}/ServerRequest.ts +0 -0
  455. /package/src/server/{primitives → core/primitives}/$action.ts +0 -0
  456. /package/src/server/{primitives → core/primitives}/$route.ts +0 -0
  457. /package/src/server/{providers → core/providers}/BunHttpServerProvider.ts +0 -0
  458. /package/src/server/{providers → core/providers}/NodeHttpServerProvider.ts +0 -0
  459. /package/src/server/{providers → core/providers}/ServerBodyParserProvider.ts +0 -0
  460. /package/src/server/{providers → core/providers}/ServerLoggerProvider.ts +0 -0
  461. /package/src/server/{providers → core/providers}/ServerNotReadyProvider.ts +0 -0
  462. /package/src/server/{providers → core/providers}/ServerProvider.ts +0 -0
  463. /package/src/server/{providers → core/providers}/ServerRouterProvider.ts +0 -0
  464. /package/src/server/{providers → core/providers}/ServerTimingProvider.ts +0 -0
  465. /package/src/server/{schemas → core/schemas}/errorSchema.ts +0 -0
  466. /package/src/server/{schemas → core/schemas}/okSchema.ts +0 -0
  467. /package/src/server/{services → core/services}/HttpClient.ts +0 -0
  468. /package/src/server/{services → core/services}/ServerRequestParser.ts +0 -0
  469. /package/src/server/{services → core/services}/UserAgentParser.ts +0 -0
  470. /package/src/{server-cors → server/cors}/index.ts +0 -0
  471. /package/src/{server-cors → server/cors}/primitives/$cors.ts +0 -0
  472. /package/src/{server-cors → server/cors}/providers/ServerCorsProvider.ts +0 -0
  473. /package/src/{server-health → server/health}/index.ts +0 -0
  474. /package/src/{server-health → server/health}/providers/ServerHealthProvider.ts +0 -0
  475. /package/src/{server-health → server/health}/schemas/healthSchema.ts +0 -0
  476. /package/src/{server-helmet → server/helmet}/index.ts +0 -0
  477. /package/src/{server-helmet → server/helmet}/providers/ServerHelmetProvider.ts +0 -0
  478. /package/src/{server-links → server/links}/index.browser.ts +0 -0
  479. /package/src/{server-links → server/links}/index.ts +0 -0
  480. /package/src/{server-links → server/links}/primitives/$client.ts +0 -0
  481. /package/src/{server-links → server/links}/primitives/$remote.ts +0 -0
  482. /package/src/{server-links → server/links}/providers/LinkProvider.ts +0 -0
  483. /package/src/{server-links → server/links}/providers/RemotePrimitiveProvider.ts +0 -0
  484. /package/src/{server-links → server/links}/providers/ServerLinksProvider.ts +0 -0
  485. /package/src/{server-links → server/links}/schemas/apiLinksResponseSchema.ts +0 -0
  486. /package/src/{server-metrics → server/metrics}/index.ts +0 -0
  487. /package/src/{server-metrics → server/metrics}/providers/ServerMetricsProvider.ts +0 -0
  488. /package/src/{server-multipart → server/multipart}/index.ts +0 -0
  489. /package/src/{server-multipart → server/multipart}/providers/ServerMultipartProvider.ts +0 -0
  490. /package/src/{server-proxy → server/proxy}/index.ts +0 -0
  491. /package/src/{server-proxy → server/proxy}/primitives/$proxy.ts +0 -0
  492. /package/src/{server-proxy → server/proxy}/providers/ServerProxyProvider.ts +0 -0
  493. /package/src/{server-rate-limit → server/rate-limit}/primitives/$rateLimit.ts +0 -0
  494. /package/src/{server-rate-limit → server/rate-limit}/providers/ServerRateLimitProvider.ts +0 -0
  495. /package/src/{server-security → server/security}/index.browser.ts +0 -0
  496. /package/src/{server-security → server/security}/index.ts +0 -0
  497. /package/src/{server-security → server/security}/primitives/$basicAuth.ts +0 -0
  498. /package/src/{server-security → server/security}/providers/ServerBasicAuthProvider.ts +0 -0
  499. /package/src/{server-security → server/security}/providers/ServerSecurityProvider.ts +0 -0
  500. /package/src/{server-static → server/static}/index.ts +0 -0
  501. /package/src/{server-static → server/static}/primitives/$serve.ts +0 -0
  502. /package/src/{server-static → server/static}/providers/ServerStaticProvider.ts +0 -0
  503. /package/src/{server-swagger → server/swagger}/index.ts +0 -0
  504. /package/src/{server-swagger → server/swagger}/primitives/$swagger.ts +0 -0
  505. /package/src/topic/{errors → core/errors}/TopicTimeoutError.ts +0 -0
  506. /package/src/topic/{index.ts → core/index.ts} +0 -0
  507. /package/src/topic/{primitives → core/primitives}/$subscriber.ts +0 -0
  508. /package/src/topic/{primitives → core/primitives}/$topic.ts +0 -0
  509. /package/src/topic/{providers → core/providers}/MemoryTopicProvider.ts +0 -0
  510. /package/src/topic/{providers → core/providers}/TopicProvider.ts +0 -0
  511. /package/src/{topic-redis → topic/redis}/index.ts +0 -0
  512. /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
- const filepath = this.url.replace("sqlite://", "");
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 primitives.
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` primitive
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
- * Push one or more payloads to the queue for background processing.
348
- *
349
- * Jobs will be processed with crash recovery, retries (if configured),
350
- * and proper lifecycle management.
351
- *
352
- * @param payloads - One or more payloads to queue
353
- */
354
- public async push(...payloads: Array<Static<T>>): Promise<void>;
355
- /**
356
- * Push a payload to the queue with specific options.
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
- await Promise.all(
400
- payloads.map((p) => {
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
+ }