alepha 0.18.2 → 0.18.3

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 (397) hide show
  1. package/assets/devtools-ui/200.html +2 -2
  2. package/assets/devtools-ui/200.html.br +0 -0
  3. package/assets/devtools-ui/404.html +2 -2
  4. package/assets/devtools-ui/404.html.br +0 -0
  5. package/assets/devtools-ui/{asset.BfSBZ5Dd.css → asset.hG_f8HuK.css} +1 -1
  6. package/assets/devtools-ui/asset.hG_f8HuK.css.br +0 -0
  7. package/assets/devtools-ui/chunk.B3au4Lhg.js +1 -0
  8. package/assets/devtools-ui/chunk.B3au4Lhg.js.br +0 -0
  9. package/assets/devtools-ui/chunk.BLOrlnMB.js +1 -0
  10. package/assets/devtools-ui/chunk.BLOrlnMB.js.br +0 -0
  11. package/assets/devtools-ui/chunk.BLR01ljW.js +1 -0
  12. package/assets/devtools-ui/chunk.BLR01ljW.js.br +0 -0
  13. package/assets/devtools-ui/chunk.BTXaIUlA.js +1 -0
  14. package/assets/devtools-ui/chunk.BTXaIUlA.js.br +0 -0
  15. package/assets/devtools-ui/{chunk.lJL-lgnW.js → chunk.BhJaxmm8.js} +1 -1
  16. package/assets/devtools-ui/chunk.BhJaxmm8.js.br +0 -0
  17. package/assets/devtools-ui/chunk.BtoNxFuL.js +1 -0
  18. package/assets/devtools-ui/chunk.BtoNxFuL.js.br +0 -0
  19. package/assets/devtools-ui/chunk.C8YUV2Wd.js +1 -0
  20. package/assets/devtools-ui/chunk.C8YUV2Wd.js.br +0 -0
  21. package/assets/devtools-ui/{chunk.M6wyKO_3.js → chunk.CBbIgDzE.js} +2 -2
  22. package/assets/devtools-ui/chunk.CBbIgDzE.js.br +0 -0
  23. package/assets/devtools-ui/chunk.CFqIniwA.js +1 -0
  24. package/assets/devtools-ui/chunk.CFqIniwA.js.br +0 -0
  25. package/assets/devtools-ui/chunk.CLFF7f7-.js +1 -0
  26. package/assets/devtools-ui/chunk.CLFF7f7-.js.br +0 -0
  27. package/assets/devtools-ui/chunk.CRsBbA10.js +1 -0
  28. package/assets/devtools-ui/chunk.CRsBbA10.js.br +0 -0
  29. package/assets/devtools-ui/{chunk.DbEH1oOB.js → chunk.CZPo6v95.js} +1 -1
  30. package/assets/devtools-ui/chunk.CZPo6v95.js.br +0 -0
  31. package/assets/devtools-ui/chunk.D0fWgNos.js +1 -0
  32. package/assets/devtools-ui/chunk.D0fWgNos.js.br +1 -0
  33. package/assets/devtools-ui/chunk.D7-0ziQ6.js +1 -0
  34. package/assets/devtools-ui/chunk.D7-0ziQ6.js.br +0 -0
  35. package/assets/devtools-ui/chunk.DAewe0vm.js +1 -0
  36. package/assets/devtools-ui/chunk.DAewe0vm.js.br +0 -0
  37. package/assets/devtools-ui/chunk.DJRQEYqK.js +1 -0
  38. package/assets/devtools-ui/chunk.DJRQEYqK.js.br +0 -0
  39. package/assets/devtools-ui/{chunk.CZl6J9DF.js → chunk.DMAxv14p.js} +1 -1
  40. package/assets/devtools-ui/chunk.DMAxv14p.js.br +0 -0
  41. package/assets/devtools-ui/{chunk.BT2IiBkZ.js → chunk.DMImnNjU.js} +1 -1
  42. package/assets/devtools-ui/chunk.DMImnNjU.js.br +0 -0
  43. package/assets/devtools-ui/chunk.DeeQsidk.js +9 -0
  44. package/assets/devtools-ui/chunk.DeeQsidk.js.br +0 -0
  45. package/assets/devtools-ui/chunk.DqEwn9Vj.js +7 -0
  46. package/assets/devtools-ui/chunk.DqEwn9Vj.js.br +0 -0
  47. package/assets/devtools-ui/chunk.Dt8OsQey.js +1 -0
  48. package/assets/devtools-ui/chunk.Dt8OsQey.js.br +0 -0
  49. package/assets/devtools-ui/{chunk.B9pX3zit.js → chunk.Dtp8oa_f.js} +1 -1
  50. package/assets/devtools-ui/chunk.Dtp8oa_f.js.br +0 -0
  51. package/assets/devtools-ui/chunk.Dx3JzAYM.js +1 -0
  52. package/assets/devtools-ui/chunk.Dx3JzAYM.js.br +0 -0
  53. package/assets/devtools-ui/chunk.GCOj1-5E.js +1 -0
  54. package/assets/devtools-ui/chunk.GCOj1-5E.js.br +0 -0
  55. package/assets/devtools-ui/chunk.IC1LD8BH.js +1 -0
  56. package/assets/devtools-ui/chunk.IC1LD8BH.js.br +0 -0
  57. package/assets/devtools-ui/chunk.IwuB_TqW.js +1 -0
  58. package/assets/devtools-ui/chunk.IwuB_TqW.js.br +0 -0
  59. package/assets/devtools-ui/chunk.Qqapj2zq.js +1 -0
  60. package/assets/devtools-ui/chunk.Qqapj2zq.js.br +0 -0
  61. package/assets/devtools-ui/{chunk.C79YouPp.js → chunk.TKKKndOy.js} +1 -1
  62. package/assets/devtools-ui/chunk.TKKKndOy.js.br +0 -0
  63. package/assets/devtools-ui/chunk.YHTVhFQT.js +1 -0
  64. package/assets/devtools-ui/chunk.YHTVhFQT.js.br +0 -0
  65. package/assets/devtools-ui/chunk.fnod6uEi.js +1 -0
  66. package/assets/devtools-ui/chunk.fnod6uEi.js.br +0 -0
  67. package/assets/devtools-ui/chunk.mOCRmXjo.js +1 -0
  68. package/assets/devtools-ui/chunk.mOCRmXjo.js.br +0 -0
  69. package/assets/devtools-ui/chunk.qZTNEAK0.js +1 -0
  70. package/assets/devtools-ui/chunk.qZTNEAK0.js.br +0 -0
  71. package/assets/devtools-ui/chunk.rc9m0y4-.js +1 -0
  72. package/assets/devtools-ui/chunk.rc9m0y4-.js.br +0 -0
  73. package/assets/devtools-ui/entry.Cxc5QLCU.js +80 -0
  74. package/assets/devtools-ui/entry.Cxc5QLCU.js.br +0 -0
  75. package/assets/devtools-ui/index.html +2 -2
  76. package/assets/devtools-ui/index.html.br +0 -0
  77. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  78. package/assets/swagger-ui/swagger-ui.css +1 -1
  79. package/dist/api/audits/index.d.ts +61 -5
  80. package/dist/api/audits/index.d.ts.map +1 -1
  81. package/dist/api/files/index.d.ts +61 -5
  82. package/dist/api/files/index.d.ts.map +1 -1
  83. package/dist/api/jobs/index.d.ts +61 -5
  84. package/dist/api/jobs/index.d.ts.map +1 -1
  85. package/dist/api/jobs/index.js +4 -2
  86. package/dist/api/jobs/index.js.map +1 -1
  87. package/dist/api/keys/index.d.ts +5 -5
  88. package/dist/api/notifications/index.browser.js +44 -1
  89. package/dist/api/notifications/index.browser.js.map +1 -1
  90. package/dist/api/notifications/index.d.ts +187 -2
  91. package/dist/api/notifications/index.d.ts.map +1 -1
  92. package/dist/api/notifications/index.js +143 -8
  93. package/dist/api/notifications/index.js.map +1 -1
  94. package/dist/api/parameters/index.d.ts +61 -5
  95. package/dist/api/parameters/index.d.ts.map +1 -1
  96. package/dist/api/users/index.d.ts +330 -93
  97. package/dist/api/users/index.d.ts.map +1 -1
  98. package/dist/api/users/index.js +27 -36
  99. package/dist/api/users/index.js.map +1 -1
  100. package/dist/cli/config/index.d.ts +46 -0
  101. package/dist/cli/config/index.d.ts.map +1 -0
  102. package/dist/cli/config/index.js +20 -0
  103. package/dist/cli/config/index.js.map +1 -0
  104. package/dist/cli/core/index.d.ts +69 -66
  105. package/dist/cli/core/index.d.ts.map +1 -1
  106. package/dist/cli/core/index.js +329 -196
  107. package/dist/cli/core/index.js.map +1 -1
  108. package/dist/cli/platform/index.d.ts +302 -63
  109. package/dist/cli/platform/index.d.ts.map +1 -1
  110. package/dist/cli/platform/index.js +455 -25
  111. package/dist/cli/platform/index.js.map +1 -1
  112. package/dist/core/index.browser.js +125 -87
  113. package/dist/core/index.browser.js.map +1 -1
  114. package/dist/core/index.d.ts +62 -53
  115. package/dist/core/index.d.ts.map +1 -1
  116. package/dist/core/index.js +125 -87
  117. package/dist/core/index.js.map +1 -1
  118. package/dist/core/index.native.js +125 -87
  119. package/dist/core/index.native.js.map +1 -1
  120. package/dist/core/index.workerd.js +125 -87
  121. package/dist/core/index.workerd.js.map +1 -1
  122. package/dist/crypto/index.d.ts +18 -1
  123. package/dist/crypto/index.d.ts.map +1 -1
  124. package/dist/crypto/index.js +29 -3
  125. package/dist/crypto/index.js.map +1 -1
  126. package/dist/devtools/index.js +3 -12
  127. package/dist/devtools/index.js.map +1 -1
  128. package/dist/logger/index.d.ts +10 -1
  129. package/dist/logger/index.d.ts.map +1 -1
  130. package/dist/logger/index.js +19 -9
  131. package/dist/logger/index.js.map +1 -1
  132. package/dist/orm/core/index.browser.js +57 -1
  133. package/dist/orm/core/index.browser.js.map +1 -1
  134. package/dist/orm/core/index.bun.js +378 -19
  135. package/dist/orm/core/index.bun.js.map +1 -1
  136. package/dist/orm/core/index.d.ts +328 -9
  137. package/dist/orm/core/index.d.ts.map +1 -1
  138. package/dist/orm/core/index.js +384 -21
  139. package/dist/orm/core/index.js.map +1 -1
  140. package/dist/orm/postgres/index.bun.js +49 -17
  141. package/dist/orm/postgres/index.bun.js.map +1 -1
  142. package/dist/orm/postgres/index.d.ts +47 -21
  143. package/dist/orm/postgres/index.d.ts.map +1 -1
  144. package/dist/orm/postgres/index.js +52 -17
  145. package/dist/orm/postgres/index.js.map +1 -1
  146. package/dist/react/core/index.d.ts +1 -1
  147. package/dist/react/core/index.d.ts.map +1 -1
  148. package/dist/react/core/index.js +6 -1
  149. package/dist/react/core/index.js.map +1 -1
  150. package/dist/react/form/index.d.ts +28 -18
  151. package/dist/react/form/index.d.ts.map +1 -1
  152. package/dist/react/form/index.js +92 -56
  153. package/dist/react/form/index.js.map +1 -1
  154. package/dist/react/router/index.browser.js +448 -116
  155. package/dist/react/router/index.browser.js.map +1 -1
  156. package/dist/react/router/index.d.ts +102 -40
  157. package/dist/react/router/index.d.ts.map +1 -1
  158. package/dist/react/router/index.js +453 -92
  159. package/dist/react/router/index.js.map +1 -1
  160. package/dist/security/index.d.ts +3 -11
  161. package/dist/security/index.d.ts.map +1 -1
  162. package/dist/security/index.js +6 -11
  163. package/dist/security/index.js.map +1 -1
  164. package/dist/server/auth/index.d.ts +22 -24
  165. package/dist/server/auth/index.d.ts.map +1 -1
  166. package/dist/server/auth/index.js +102 -82
  167. package/dist/server/auth/index.js.map +1 -1
  168. package/dist/server/cookies/index.d.ts +7 -4
  169. package/dist/server/cookies/index.d.ts.map +1 -1
  170. package/dist/server/cookies/index.js +13 -12
  171. package/dist/server/cookies/index.js.map +1 -1
  172. package/dist/server/core/index.d.ts +288 -4
  173. package/dist/server/core/index.d.ts.map +1 -1
  174. package/dist/server/core/index.js +375 -2
  175. package/dist/server/core/index.js.map +1 -1
  176. package/dist/server/links/index.browser.js +10 -71
  177. package/dist/server/links/index.browser.js.map +1 -1
  178. package/dist/server/links/index.d.ts +32 -49
  179. package/dist/server/links/index.d.ts.map +1 -1
  180. package/dist/server/links/index.js +73 -100
  181. package/dist/server/links/index.js.map +1 -1
  182. package/dist/system/index.browser.js +221 -2
  183. package/dist/system/index.browser.js.map +1 -1
  184. package/dist/system/index.d.ts +63 -1
  185. package/dist/system/index.d.ts.map +1 -1
  186. package/dist/system/index.js +221 -1
  187. package/dist/system/index.js.map +1 -1
  188. package/dist/system/index.workerd.js +224 -4
  189. package/dist/system/index.workerd.js.map +1 -1
  190. package/package.json +10 -5
  191. package/src/api/jobs/providers/JobProvider.ts +6 -3
  192. package/src/api/notifications/controllers/AdminNotificationController.ts +83 -0
  193. package/src/api/notifications/index.browser.ts +3 -0
  194. package/src/api/notifications/index.ts +14 -2
  195. package/src/api/notifications/jobs/NotificationJobs.ts +11 -2
  196. package/src/api/notifications/schemas/notificationDetailResourceSchema.ts +20 -0
  197. package/src/api/notifications/schemas/notificationQuerySchema.ts +19 -0
  198. package/src/api/notifications/schemas/notificationResourceSchema.ts +18 -0
  199. package/src/api/notifications/services/NotificationSenderService.ts +15 -2
  200. package/src/api/users/atoms/realmAuthSettingsAtom.ts +28 -32
  201. package/src/api/users/buckets/UserBuckets.ts +1 -1
  202. package/src/api/users/jobs/UserJobs.ts +1 -1
  203. package/src/api/users/primitives/$realm.ts +8 -49
  204. package/src/api/users/providers/RealmProvider.ts +2 -3
  205. package/src/api/users/services/RegistrationService.spec.ts +7 -7
  206. package/src/api/users/services/RegistrationService.ts +3 -3
  207. package/src/api/users/services/SessionService.spec.ts +4 -4
  208. package/src/api/users/services/SessionService.ts +3 -3
  209. package/src/cli/{core → config}/defineConfig.ts +14 -20
  210. package/src/cli/config/index.ts +1 -0
  211. package/src/cli/core/commands/db.ts +65 -1
  212. package/src/cli/core/commands/dev.ts +1 -0
  213. package/src/cli/core/commands/init.ts +2 -192
  214. package/src/cli/core/index.ts +34 -11
  215. package/src/cli/core/providers/ViteDevServerProvider.ts +52 -13
  216. package/src/cli/core/services/PackageManagerUtils.ts +43 -21
  217. package/src/cli/core/services/ProjectScaffolder.ts +214 -2
  218. package/src/cli/core/services/ViteUtils.ts +57 -0
  219. package/src/cli/core/tasks/BuildClientTask.ts +7 -2
  220. package/src/cli/core/tasks/BuildCloudflareTask.ts +4 -12
  221. package/src/cli/core/tasks/BuildServerTask.ts +2 -0
  222. package/src/cli/core/tasks/BuildVercelTask.ts +165 -168
  223. package/src/cli/core/templates/alephaConfigTs.ts +1 -1
  224. package/src/cli/core/templates/apiAppSecurityTs.ts +5 -8
  225. package/src/cli/core/templates/tsconfigJson.ts +6 -1
  226. package/src/cli/platform/adapters/CloudflareAdapter.spec.ts +1 -1
  227. package/src/cli/platform/adapters/CloudflareAdapter.ts +30 -29
  228. package/src/cli/platform/atoms/platformOptions.ts +21 -0
  229. package/src/cli/platform/commands/SecretsCommand.spec.ts +298 -0
  230. package/src/cli/platform/commands/SecretsCommand.ts +283 -0
  231. package/src/cli/platform/commands/platform.ts +12 -0
  232. package/src/cli/platform/index.ts +14 -28
  233. package/src/cli/platform/providers/GitHubSecretStore.spec.ts +153 -0
  234. package/src/cli/platform/providers/GitHubSecretStore.ts +112 -0
  235. package/src/cli/platform/providers/MemorySecretStore.ts +114 -0
  236. package/src/cli/platform/providers/SecretStoreProvider.ts +39 -0
  237. package/src/cli/platform/schemas/cloudflare.ts +2 -0
  238. package/src/cli/platform/services/CloudflareApi.ts +5 -2
  239. package/src/cli/platform/services/DockerComposeGenerator.spec.ts +115 -0
  240. package/src/cli/platform/services/DockerComposeGenerator.ts +46 -1
  241. package/src/cli/platform/services/SecretFilterService.spec.ts +111 -0
  242. package/src/cli/platform/services/SecretFilterService.ts +54 -0
  243. package/src/core/Alepha.ts +94 -25
  244. package/src/core/__tests__/Alepha-parseEnv.spec.ts +20 -0
  245. package/src/core/primitives/$memoize.ts +38 -26
  246. package/src/core/providers/AlsProvider.ts +2 -0
  247. package/src/core/providers/EventManager.ts +4 -0
  248. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +1 -4
  249. package/src/core/providers/KeylessJsonSchemaCodec.ts +19 -125
  250. package/src/core/providers/SchemaValidator.spec.ts +36 -0
  251. package/src/core/providers/SchemaValidator.ts +9 -0
  252. package/src/crypto/index.ts +6 -1
  253. package/src/crypto/providers/SecretProvider.ts +36 -0
  254. package/src/devtools/providers/DevToolsProvider.ts +3 -12
  255. package/src/logger/index.ts +33 -6
  256. package/src/logger/providers/PrettyFormatterProvider.ts +5 -3
  257. package/src/orm/__tests__/orm-next-tests.ts +492 -0
  258. package/src/orm/__tests__/orm-next.spec.ts +140 -0
  259. package/src/orm/core/constants/PG_SYMBOLS.ts +17 -0
  260. package/src/orm/core/index.bun.ts +3 -6
  261. package/src/orm/core/index.shared-server.ts +2 -0
  262. package/src/orm/core/index.shared.ts +2 -0
  263. package/src/orm/core/index.ts +5 -7
  264. package/src/orm/core/interfaces/AggregateQuery.ts +103 -0
  265. package/src/orm/core/interfaces/PgQueryWhere.ts +7 -0
  266. package/src/orm/core/primitives/$entity.ts +8 -0
  267. package/src/orm/core/primitives/$repository.ts +6 -3
  268. package/src/orm/core/primitives/$view.ts +88 -0
  269. package/src/orm/core/providers/DbCacheProvider.ts +66 -0
  270. package/src/orm/core/providers/DrizzleKitProvider.ts +42 -0
  271. package/src/orm/core/providers/drivers/BunSqliteProvider.ts +2 -3
  272. package/src/orm/core/providers/drivers/CloudflareD1Provider.ts +12 -0
  273. package/src/orm/core/providers/drivers/DatabaseProvider.ts +39 -0
  274. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +2 -3
  275. package/src/orm/core/schemas/databaseEnvSchema.ts +31 -0
  276. package/src/orm/core/schemas/insertSchema.ts +13 -3
  277. package/src/orm/core/schemas/updateSchema.ts +14 -3
  278. package/src/orm/core/services/ModelBuilder.ts +26 -14
  279. package/src/orm/core/services/QueryManager.ts +13 -0
  280. package/src/orm/core/services/Repository.ts +307 -5
  281. package/src/orm/core/services/SqliteModelBuilder.ts +38 -0
  282. package/src/orm/postgres/index.bun.ts +4 -7
  283. package/src/orm/postgres/index.ts +4 -7
  284. package/src/orm/postgres/providers/BunPostgresProvider.ts +12 -2
  285. package/src/orm/postgres/providers/NodePostgresProvider.ts +7 -0
  286. package/src/orm/postgres/providers/PglitePostgresProvider.ts +10 -17
  287. package/src/orm/postgres/providers/PostgresProvider.ts +7 -36
  288. package/src/orm/postgres/schemas/postgresEnvSchema.ts +32 -0
  289. package/src/orm/postgres/services/PostgresModelBuilder.ts +40 -0
  290. package/src/react/core/components/ErrorBoundary.tsx +5 -2
  291. package/src/react/form/hooks/useFieldValue.ts +34 -0
  292. package/src/react/form/hooks/useForm.browser.spec.tsx +94 -9
  293. package/src/react/form/hooks/useForm.ts +14 -2
  294. package/src/react/form/hooks/useFormState.ts +10 -10
  295. package/src/react/form/hooks/useFormValues.ts +29 -0
  296. package/src/react/form/index.ts +3 -1
  297. package/src/react/form/services/FormModel.ts +53 -122
  298. package/src/react/router/components/ErrorViewer.tsx +333 -34
  299. package/src/react/router/components/NestedView.tsx +10 -3
  300. package/src/react/router/primitives/$page.browser.spec.tsx +34 -0
  301. package/src/react/router/primitives/$page.spec.tsx +20 -0
  302. package/src/react/router/primitives/$page.ts +24 -0
  303. package/src/react/router/providers/ReactBrowserRouterProvider.ts +14 -2
  304. package/src/react/router/providers/ReactPageProvider.ts +156 -73
  305. package/src/react/router/providers/ReactServerProvider.ts +40 -2
  306. package/src/react/router/providers/ReactServerTemplateProvider.ts +13 -1
  307. package/src/security/providers/SecurityProvider.ts +5 -27
  308. package/src/server/auth/primitives/$auth.ts +52 -19
  309. package/src/server/auth/providers/ServerAuthProvider.ts +145 -139
  310. package/src/server/cookies/providers/ServerCookiesProvider.ts +12 -24
  311. package/src/server/core/index.ts +3 -1
  312. package/src/server/core/primitives/$sse.spec.ts +315 -0
  313. package/src/server/core/primitives/$sse.ts +715 -0
  314. package/src/server/links/index.browser.ts +1 -3
  315. package/src/server/links/index.ts +0 -3
  316. package/src/server/links/providers/LinkProvider.spec.ts +12 -21
  317. package/src/server/links/providers/LinkProvider.ts +20 -52
  318. package/src/server/links/providers/ServerLinksProvider.spec.ts +106 -0
  319. package/src/server/links/providers/ServerLinksProvider.ts +113 -73
  320. package/src/server/links/schemas/apiLinksResponseSchema.ts +4 -21
  321. package/src/server/links/services/BatchCollector.ts +5 -3
  322. package/src/system/index.browser.ts +1 -0
  323. package/src/system/index.ts +3 -0
  324. package/src/system/index.workerd.ts +39 -1
  325. package/src/system/providers/WorkerdFileSystemProvider.ts +365 -0
  326. package/assets/devtools-ui/asset.BfSBZ5Dd.css.br +0 -0
  327. package/assets/devtools-ui/chunk.2NYaoqWt.js +0 -1
  328. package/assets/devtools-ui/chunk.2NYaoqWt.js.br +0 -0
  329. package/assets/devtools-ui/chunk.B052Z_xQ.js +0 -1
  330. package/assets/devtools-ui/chunk.B052Z_xQ.js.br +0 -0
  331. package/assets/devtools-ui/chunk.B4kVY90C.js +0 -1
  332. package/assets/devtools-ui/chunk.B4kVY90C.js.br +0 -0
  333. package/assets/devtools-ui/chunk.B7QJXctB.js +0 -1
  334. package/assets/devtools-ui/chunk.B7QJXctB.js.br +0 -0
  335. package/assets/devtools-ui/chunk.B9pX3zit.js.br +0 -0
  336. package/assets/devtools-ui/chunk.BKF9JxIo.js +0 -1
  337. package/assets/devtools-ui/chunk.BKF9JxIo.js.br +0 -0
  338. package/assets/devtools-ui/chunk.BOHgdTP-.js +0 -1
  339. package/assets/devtools-ui/chunk.BOHgdTP-.js.br +0 -0
  340. package/assets/devtools-ui/chunk.BOVFxkYC.js +0 -1
  341. package/assets/devtools-ui/chunk.BOVFxkYC.js.br +0 -0
  342. package/assets/devtools-ui/chunk.BR842zj5.js +0 -1
  343. package/assets/devtools-ui/chunk.BR842zj5.js.br +0 -0
  344. package/assets/devtools-ui/chunk.BT2IiBkZ.js.br +0 -0
  345. package/assets/devtools-ui/chunk.C79YouPp.js.br +0 -0
  346. package/assets/devtools-ui/chunk.C8mlBrjW.js +0 -9
  347. package/assets/devtools-ui/chunk.C8mlBrjW.js.br +0 -0
  348. package/assets/devtools-ui/chunk.CK0ow3AZ.js +0 -1
  349. package/assets/devtools-ui/chunk.CK0ow3AZ.js.br +0 -0
  350. package/assets/devtools-ui/chunk.CZl6J9DF.js.br +0 -0
  351. package/assets/devtools-ui/chunk.CdNr0YzS.js +0 -1
  352. package/assets/devtools-ui/chunk.CdNr0YzS.js.br +0 -0
  353. package/assets/devtools-ui/chunk.Ce6_6iIF.js +0 -1
  354. package/assets/devtools-ui/chunk.Ce6_6iIF.js.br +0 -0
  355. package/assets/devtools-ui/chunk.CpyDMr6O.js +0 -1
  356. package/assets/devtools-ui/chunk.CpyDMr6O.js.br +0 -0
  357. package/assets/devtools-ui/chunk.CyPmvPnY.js +0 -1
  358. package/assets/devtools-ui/chunk.CyPmvPnY.js.br +0 -0
  359. package/assets/devtools-ui/chunk.DTI_geWu.js +0 -1
  360. package/assets/devtools-ui/chunk.DTI_geWu.js.br +0 -0
  361. package/assets/devtools-ui/chunk.DbEH1oOB.js.br +0 -0
  362. package/assets/devtools-ui/chunk.Ddeqj5gv.js +0 -1
  363. package/assets/devtools-ui/chunk.Ddeqj5gv.js.br +0 -0
  364. package/assets/devtools-ui/chunk.DpRnB4vJ.js +0 -1
  365. package/assets/devtools-ui/chunk.DpRnB4vJ.js.br +0 -0
  366. package/assets/devtools-ui/chunk.DxPGTlsg.js +0 -1
  367. package/assets/devtools-ui/chunk.DxPGTlsg.js.br +0 -0
  368. package/assets/devtools-ui/chunk.G7_MMBJS.js +0 -1
  369. package/assets/devtools-ui/chunk.G7_MMBJS.js.br +0 -0
  370. package/assets/devtools-ui/chunk.M6wyKO_3.js.br +0 -0
  371. package/assets/devtools-ui/chunk.OUxNGmQ6.js +0 -1
  372. package/assets/devtools-ui/chunk.OUxNGmQ6.js.br +0 -0
  373. package/assets/devtools-ui/chunk.T1kle-fF.js +0 -1
  374. package/assets/devtools-ui/chunk.T1kle-fF.js.br +0 -0
  375. package/assets/devtools-ui/chunk.WjpsbQAv.js +0 -1
  376. package/assets/devtools-ui/chunk.WjpsbQAv.js.br +0 -0
  377. package/assets/devtools-ui/chunk.c6YgVx86.js +0 -1
  378. package/assets/devtools-ui/chunk.c6YgVx86.js.br +0 -0
  379. package/assets/devtools-ui/chunk.dwU3E_MU.js +0 -1
  380. package/assets/devtools-ui/chunk.dwU3E_MU.js.br +0 -0
  381. package/assets/devtools-ui/chunk.lJL-lgnW.js.br +0 -0
  382. package/assets/devtools-ui/chunk.lPWRmvA-.js +0 -7
  383. package/assets/devtools-ui/chunk.lPWRmvA-.js.br +0 -0
  384. package/assets/devtools-ui/chunk.p3HJvugM.js +0 -1
  385. package/assets/devtools-ui/chunk.p3HJvugM.js.br +0 -0
  386. package/assets/devtools-ui/chunk.r_Xoa_CI.js +0 -1
  387. package/assets/devtools-ui/chunk.r_Xoa_CI.js.br +0 -0
  388. package/assets/devtools-ui/chunk.sRNuTYXb.js +0 -1
  389. package/assets/devtools-ui/chunk.sRNuTYXb.js.br +0 -0
  390. package/assets/devtools-ui/chunk.tUjcyX5C.js +0 -1
  391. package/assets/devtools-ui/chunk.tUjcyX5C.js.br +0 -0
  392. package/assets/devtools-ui/chunk.thjBxvCA.js +0 -1
  393. package/assets/devtools-ui/chunk.thjBxvCA.js.br +0 -0
  394. package/assets/devtools-ui/entry.GYhBVRpC.js +0 -78
  395. package/assets/devtools-ui/entry.GYhBVRpC.js.br +0 -0
  396. package/src/server/links/services/DefinitionsPool.spec.ts +0 -86
  397. package/src/server/links/services/DefinitionsPool.ts +0 -43
@@ -82,6 +82,9 @@ export class DockerComposeGenerator {
82
82
  this.anyAppHas(options.apps, "hasQueue")) &&
83
83
  !options.envVars.REDIS_URL;
84
84
 
85
+ const needsRustFS =
86
+ this.anyAppHas(options.apps, "hasBucket") && !options.envVars.S3_ENDPOINT;
87
+
85
88
  if (needsPostgres) {
86
89
  const dbName = `${options.project}_${options.env}`.replace(/-/g, "_");
87
90
  services.push(
@@ -110,6 +113,22 @@ export class DockerComposeGenerator {
110
113
  );
111
114
  }
112
115
 
116
+ if (needsRustFS) {
117
+ services.push(
118
+ [
119
+ " rustfs:",
120
+ " image: rustfs/rustfs:latest",
121
+ ' ports: ["9000:9000"]',
122
+ " environment:",
123
+ " RUSTFS_ROOT_USER: alepha",
124
+ " RUSTFS_ROOT_PASSWORD: alepha",
125
+ " volumes:",
126
+ " - rustfs_data:/data",
127
+ ].join("\n"),
128
+ );
129
+ volumes.push(" rustfs_data:");
130
+ }
131
+
113
132
  if (services.length === 0) {
114
133
  return null;
115
134
  }
@@ -197,6 +216,9 @@ export class DockerComposeGenerator {
197
216
  ) {
198
217
  deps.push(" - redis");
199
218
  }
219
+ if (app.resources.hasBucket && !options.envVars.S3_ENDPOINT) {
220
+ deps.push(" - rustfs");
221
+ }
200
222
  if (deps.length > 0) {
201
223
  appLines.push(" depends_on:", ...deps);
202
224
  }
@@ -244,6 +266,28 @@ export class DockerComposeGenerator {
244
266
  services.push(redisLines.join("\n"));
245
267
  }
246
268
 
269
+ // RustFS (S3-compatible object storage)
270
+ const needsRustFS =
271
+ this.anyAppHas(options.apps, "hasBucket") && !options.envVars.S3_ENDPOINT;
272
+
273
+ if (needsRustFS) {
274
+ const rustfsLines = [
275
+ " rustfs:",
276
+ " image: rustfs/rustfs:latest",
277
+ " environment:",
278
+ " RUSTFS_ROOT_USER: alepha",
279
+ " RUSTFS_ROOT_PASSWORD: ${S3_SECRET_KEY}",
280
+ " volumes:",
281
+ " - rustfs_data:/data",
282
+ ];
283
+ if (hasDomain) {
284
+ rustfsLines.push(" networks:", " - internal");
285
+ }
286
+ rustfsLines.push(" restart: unless-stopped");
287
+ services.push(rustfsLines.join("\n"));
288
+ volumes.push(" rustfs_data:");
289
+ }
290
+
247
291
  const parts = [
248
292
  "# Auto-generated by Alepha. Do not edit.",
249
293
  "services:",
@@ -302,7 +346,8 @@ export class DockerComposeGenerator {
302
346
  return (
303
347
  (this.anyAppHas(apps, "hasDatabase") && !envVars.DATABASE_URL) ||
304
348
  ((this.anyAppHas(apps, "hasKV") || this.anyAppHas(apps, "hasQueue")) &&
305
- !envVars.REDIS_URL)
349
+ !envVars.REDIS_URL) ||
350
+ (this.anyAppHas(apps, "hasBucket") && !envVars.S3_ENDPOINT)
306
351
  );
307
352
  }
308
353
  }
@@ -0,0 +1,111 @@
1
+ import { Alepha } from "alepha";
2
+ import { describe, test } from "vitest";
3
+ import { SecretFilterService } from "./SecretFilterService.ts";
4
+
5
+ describe("SecretFilterService", () => {
6
+ const createFilter = () => {
7
+ const alepha = Alepha.create();
8
+ return alepha.inject(SecretFilterService);
9
+ };
10
+
11
+ test("keeps normal secret keys", ({ expect }) => {
12
+ const filter = createFilter();
13
+ const result = filter.filter({
14
+ API_KEY: "abc123",
15
+ REDIS_URL: "redis://localhost",
16
+ });
17
+
18
+ expect(result).toEqual({
19
+ API_KEY: "abc123",
20
+ REDIS_URL: "redis://localhost",
21
+ });
22
+ });
23
+
24
+ test("keeps DATABASE_URL and POSTGRES_SCHEMA", ({ expect }) => {
25
+ const filter = createFilter();
26
+ const result = filter.filter({
27
+ DATABASE_URL: "postgres://localhost/db",
28
+ POSTGRES_SCHEMA: "public",
29
+ });
30
+
31
+ expect(result).toEqual({
32
+ DATABASE_URL: "postgres://localhost/db",
33
+ POSTGRES_SCHEMA: "public",
34
+ });
35
+ });
36
+
37
+ test("excludes NODE_ENV", ({ expect }) => {
38
+ const filter = createFilter();
39
+ const result = filter.filter({
40
+ NODE_ENV: "production",
41
+ API_KEY: "abc123",
42
+ });
43
+
44
+ expect(result).toEqual({ API_KEY: "abc123" });
45
+ });
46
+
47
+ test("excludes VITE_ prefixed keys", ({ expect }) => {
48
+ const filter = createFilter();
49
+ const result = filter.filter({
50
+ VITE_APP_TITLE: "My App",
51
+ VITE_PUBLIC_KEY: "pk_123",
52
+ API_KEY: "abc123",
53
+ });
54
+
55
+ expect(result).toEqual({ API_KEY: "abc123" });
56
+ });
57
+
58
+ test("excludes empty values", ({ expect }) => {
59
+ const filter = createFilter();
60
+ const result = filter.filter({
61
+ API_KEY: "abc123",
62
+ EMPTY_VAR: "",
63
+ });
64
+
65
+ expect(result).toEqual({ API_KEY: "abc123" });
66
+ });
67
+
68
+ test("returns empty record when all filtered", ({ expect }) => {
69
+ const filter = createFilter();
70
+ const result = filter.filter({
71
+ NODE_ENV: "production",
72
+ VITE_KEY: "value",
73
+ EMPTY: "",
74
+ });
75
+
76
+ expect(result).toEqual({});
77
+ });
78
+
79
+ describe("toRemoteName", () => {
80
+ test("prefixes GITHUB_ keys with APP_", ({ expect }) => {
81
+ const filter = createFilter();
82
+ expect(filter.toRemoteName("GITHUB_CLIENT_ID")).toBe(
83
+ "APP_GITHUB_CLIENT_ID",
84
+ );
85
+ expect(filter.toRemoteName("GITHUB_CLIENT_SECRET")).toBe(
86
+ "APP_GITHUB_CLIENT_SECRET",
87
+ );
88
+ });
89
+
90
+ test("leaves non-GITHUB_ keys unchanged", ({ expect }) => {
91
+ const filter = createFilter();
92
+ expect(filter.toRemoteName("DATABASE_URL")).toBe("DATABASE_URL");
93
+ expect(filter.toRemoteName("API_KEY")).toBe("API_KEY");
94
+ });
95
+ });
96
+
97
+ describe("toLocalName", () => {
98
+ test("strips APP_ prefix from APP_GITHUB_ keys", ({ expect }) => {
99
+ const filter = createFilter();
100
+ expect(filter.toLocalName("APP_GITHUB_CLIENT_ID")).toBe(
101
+ "GITHUB_CLIENT_ID",
102
+ );
103
+ });
104
+
105
+ test("leaves non-APP_GITHUB_ keys unchanged", ({ expect }) => {
106
+ const filter = createFilter();
107
+ expect(filter.toLocalName("DATABASE_URL")).toBe("DATABASE_URL");
108
+ expect(filter.toLocalName("APP_SECRET")).toBe("APP_SECRET");
109
+ });
110
+ });
111
+ });
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Filters environment variables for secret store syncing.
3
+ *
4
+ * Excludes platform-managed vars (NODE_ENV), build-time vars (VITE_*),
5
+ * and empty values. Keeps everything else — including DATABASE_URL
6
+ * and POSTGRES_SCHEMA which GitHub Actions needs.
7
+ *
8
+ * Also handles renaming GITHUB_* keys since GitHub Actions rejects
9
+ * secret names starting with GITHUB_.
10
+ */
11
+ export class SecretFilterService {
12
+ protected static readonly EXCLUDED_KEYS = new Set(["NODE_ENV"]);
13
+ protected static readonly GITHUB_PREFIX = "GITHUB_";
14
+ protected static readonly REMOTE_PREFIX = "APP_GITHUB_";
15
+
16
+ /**
17
+ * Return only the entries that should be pushed to a secret store.
18
+ */
19
+ public filter(envVars: Record<string, string>): Record<string, string> {
20
+ const result: Record<string, string> = {};
21
+
22
+ for (const [key, value] of Object.entries(envVars)) {
23
+ if (!value) continue;
24
+ if (SecretFilterService.EXCLUDED_KEYS.has(key)) continue;
25
+ if (key.startsWith("VITE_")) continue;
26
+ result[key] = value;
27
+ }
28
+
29
+ return result;
30
+ }
31
+
32
+ /**
33
+ * Convert a local env key to a remote secret name.
34
+ *
35
+ * GITHUB_* keys are prefixed with APP_ since GitHub Actions rejects
36
+ * secret names starting with GITHUB_.
37
+ */
38
+ public toRemoteName(key: string): string {
39
+ if (key.startsWith(SecretFilterService.GITHUB_PREFIX)) {
40
+ return `${SecretFilterService.REMOTE_PREFIX}${key.slice(SecretFilterService.GITHUB_PREFIX.length)}`;
41
+ }
42
+ return key;
43
+ }
44
+
45
+ /**
46
+ * Convert a remote secret name back to the local env key.
47
+ */
48
+ public toLocalName(remoteName: string): string {
49
+ if (remoteName.startsWith(SecretFilterService.REMOTE_PREFIX)) {
50
+ return `${SecretFilterService.GITHUB_PREFIX}${remoteName.slice(SecretFilterService.REMOTE_PREFIX.length)}`;
51
+ }
52
+ return remoteName;
53
+ }
54
+ }
@@ -236,9 +236,22 @@ export class Alepha {
236
236
  protected ready = false;
237
237
 
238
238
  /**
239
- * A promise that resolves when the App has started.
239
+ * In-flight startup promise returned by boot().
240
+ *
241
+ * Concurrent callers of start() share this same promise. Cleared on
242
+ * success, failure, or stale-detection.
243
+ */
244
+ protected startPromise?: Promise<this>;
245
+
246
+ /**
247
+ * Timestamp (performance.now) when the current boot() began.
248
+ *
249
+ * In serverless environments (e.g. Cloudflare Workers), the runtime can
250
+ * kill an invocation mid-startup without running cleanup. The global
251
+ * Alepha instance persists, leaving startPromise as a never-settling
252
+ * promise. We detect this by comparing elapsed time against STARTUP_TIMEOUT.
240
253
  */
241
- protected starting?: PromiseWithResolvers<this>;
254
+ protected startedAt = 0;
242
255
 
243
256
  /**
244
257
  * During the instantiation process, we keep a list of pending instantiations.
@@ -479,6 +492,17 @@ export class Alepha {
479
492
 
480
493
  // -------------------------------------------------------------------------------------------------------------------
481
494
 
495
+ /**
496
+ * Max time (ms) a boot() is allowed to run before being considered stale.
497
+ *
498
+ * In serverless runtimes (Cloudflare Workers, etc.) an invocation can be
499
+ * killed mid-startup. The global Alepha instance survives, but
500
+ * `startPromise` becomes a zombie that never settles.
501
+ * Any new invocation that sees an older-than-STARTUP_TIMEOUT promise
502
+ * discards it and boots fresh.
503
+ */
504
+ protected static readonly STARTUP_TIMEOUT = 30_000;
505
+
482
506
  /**
483
507
  * Starts the App.
484
508
  *
@@ -487,6 +511,10 @@ export class Alepha {
487
511
  * - Run "start" hook for all services. Providers will connect/listen/...
488
512
  * - Run "ready" hook for all services. This is the point where the App is ready to serve requests.
489
513
  *
514
+ * Concurrent callers share the same boot promise. If a previous boot was
515
+ * abandoned (serverless invocation killed), the stale promise is detected
516
+ * and a fresh boot is triggered.
517
+ *
490
518
  * @return A promise that resolves when the App has started.
491
519
  */
492
520
  public async start(): Promise<this> {
@@ -495,19 +523,36 @@ export class Alepha {
495
523
  return this;
496
524
  }
497
525
 
498
- // make sure that start is called only once
499
- if (this.starting) {
500
- this.log?.warn("App is already starting, waiting for it to finish...");
501
- return this.starting.promise;
526
+ if (this.startPromise) {
527
+ const elapsed = performance.now() - this.startedAt;
528
+ if (elapsed > Alepha.STARTUP_TIMEOUT) {
529
+ this.log?.warn(
530
+ `Previous start attempt is stale (${Math.round(elapsed)}ms ago), resetting...`,
531
+ );
532
+ this.resetStartup();
533
+ } else {
534
+ this.log?.warn("App is already starting, waiting for it to finish...");
535
+ return this.startPromise;
536
+ }
502
537
  }
503
538
 
504
- this.starting = Promise.withResolvers();
505
-
506
- try {
507
- const now = performance.now();
539
+ this.startedAt = performance.now();
540
+ this.startPromise = this.boot();
541
+ return this.startPromise;
542
+ }
508
543
 
509
- this.log?.info("Starting App...");
544
+ /**
545
+ * Perform the actual startup sequence.
546
+ *
547
+ * Separated from start() so that start() remains a thin state-machine
548
+ * and boot() owns the real work. The promise returned here is stored as
549
+ * `startPromise` and shared with concurrent callers.
550
+ */
551
+ protected async boot(): Promise<this> {
552
+ const now = performance.now();
553
+ this.log?.info("Starting App...");
510
554
 
555
+ try {
511
556
  for (const [key] of this.substitutions.entries()) {
512
557
  this.inject(key);
513
558
  }
@@ -544,17 +589,27 @@ export class Alepha {
544
589
  );
545
590
 
546
591
  this.ready = true;
592
+ return this;
547
593
  } catch (error) {
548
- this.starting.reject(error);
549
- const promise = this.starting.promise;
550
- this.starting = undefined;
551
- return promise;
594
+ this.resetStartup();
595
+ throw error;
552
596
  }
597
+ }
553
598
 
554
- this.starting.resolve(this);
555
- this.starting = undefined;
556
-
557
- return this;
599
+ /**
600
+ * Reset startup state so that a fresh boot() can be attempted.
601
+ *
602
+ * Called when:
603
+ * - boot() fails (error during configure/start/ready hooks)
604
+ * - a stale startPromise is detected (serverless invocation was killed)
605
+ */
606
+ protected resetStartup(): void {
607
+ this.startPromise = undefined;
608
+ this.startedAt = 0;
609
+ this.locked = false;
610
+ this.configured = false;
611
+ this.started = false;
612
+ this.ready = false;
558
613
  }
559
614
 
560
615
  /**
@@ -580,6 +635,8 @@ export class Alepha {
580
635
 
581
636
  this.started = false;
582
637
  this.ready = false;
638
+ this.startPromise = undefined;
639
+ this.startedAt = 0;
583
640
  }
584
641
 
585
642
  /**
@@ -893,13 +950,20 @@ export class Alepha {
893
950
 
894
951
  const config = this.codec.validate(schema, this.env) as Record<string, any>;
895
952
 
896
- for (const key in config) {
897
- if (typeof config[key] === "string") {
953
+ // Resolve $KEY references. Multiple passes handle transitive references
954
+ // where a replacement introduces a new $KEY that was already checked
955
+ // (e.g. C=$B, B=$A, A=value — single pass leaves C as "$A").
956
+ let changed = true;
957
+ for (let pass = 0; changed && pass < 10; pass++) {
958
+ changed = false;
959
+ for (const key in config) {
960
+ if (typeof config[key] !== "string") continue;
898
961
  for (const env in config) {
899
- config[key] = (config[key] as string).replaceAll(
900
- `$${env}`,
901
- String(config[env] ?? ""),
902
- );
962
+ const before = config[key] as string;
963
+ config[key] = before.replaceAll(`$${env}`, String(config[env] ?? ""));
964
+ if (config[key] !== before) {
965
+ changed = true;
966
+ }
903
967
  }
904
968
  }
905
969
  }
@@ -1160,6 +1224,11 @@ export interface Env {
1160
1224
  * Optional root module name.
1161
1225
  */
1162
1226
  MODULE_NAME?: string;
1227
+
1228
+ /**
1229
+ * The secret key used for signing JWTs, encrypting cookies, and other security features.
1230
+ */
1231
+ APP_SECRET?: string;
1163
1232
  }
1164
1233
 
1165
1234
  // ---------------------------------------------------------------------------------------------------------------------
@@ -84,6 +84,26 @@ describe("Alepha#parseEnv", () => {
84
84
  expect(env.URL).toBe("$host");
85
85
  });
86
86
 
87
+ it("should resolve transitive $KEY references", async () => {
88
+ const schema = t.object({
89
+ A: t.optional(t.text()),
90
+ B: t.optional(t.text()),
91
+ C: t.optional(t.text()),
92
+ });
93
+
94
+ const alepha = Alepha.create({
95
+ env: {
96
+ A: "value",
97
+ B: "$A",
98
+ C: "$B",
99
+ },
100
+ });
101
+
102
+ const env = alepha.parseEnv(schema);
103
+ expect(env.B).toBe("value");
104
+ expect(env.C).toBe("value");
105
+ });
106
+
87
107
  it("should return cached result for same schema", async () => {
88
108
  const schema = t.object({
89
109
  FOO: t.optional(t.text()),
@@ -1,21 +1,5 @@
1
1
  import { createMiddleware, type Middleware } from "alepha";
2
2
 
3
- export interface MemoizeOptions {
4
- /**
5
- * Maximum number of entries to keep in the cache.
6
- * When exceeded, the oldest entry is evicted (FIFO).
7
- *
8
- * @default 1000
9
- */
10
- max?: number;
11
-
12
- /**
13
- * Custom key function. Receives the handler's arguments.
14
- * By default, `JSON.stringify(args)` is used.
15
- */
16
- key?: (...args: any[]) => string;
17
- }
18
-
19
3
  /**
20
4
  * Lightweight in-process memoization middleware.
21
5
  *
@@ -48,20 +32,48 @@ export const $memoize = (options?: MemoizeOptions): Middleware => {
48
32
  return store.get(key);
49
33
  }
50
34
 
51
- const result = await next(...args);
35
+ // Store the promise immediately to deduplicate concurrent calls
36
+ // for the same key (thundering herd prevention).
37
+ const promise = next(...args);
38
+ store.set(key, promise);
52
39
 
53
- // Evict oldest if at capacity
54
- if (store.size >= maxSize) {
55
- const firstKey = store.keys().next().value;
56
- if (firstKey !== undefined) {
57
- store.delete(firstKey);
58
- }
59
- }
40
+ try {
41
+ const result = await promise;
60
42
 
61
- store.set(key, result);
43
+ // Replace the promise with the resolved value
44
+ store.set(key, result);
62
45
 
63
- return result;
46
+ // Evict oldest if at capacity
47
+ if (store.size > maxSize) {
48
+ const firstKey = store.keys().next().value;
49
+ if (firstKey !== undefined) {
50
+ store.delete(firstKey);
51
+ }
52
+ }
53
+
54
+ return result;
55
+ } catch (error) {
56
+ // Don't cache failed results
57
+ store.delete(key);
58
+ throw error;
59
+ }
64
60
  };
65
61
  },
66
62
  });
67
63
  };
64
+
65
+ export interface MemoizeOptions {
66
+ /**
67
+ * Maximum number of entries to keep in the cache.
68
+ * When exceeded, the oldest entry is evicted (FIFO).
69
+ *
70
+ * @default 1000
71
+ */
72
+ max?: number;
73
+
74
+ /**
75
+ * Custom key function. Receives the handler's arguments.
76
+ * By default, `JSON.stringify(args)` is used.
77
+ */
78
+ key?: (...args: any[]) => string;
79
+ }
@@ -27,6 +27,8 @@ export class AlsProvider {
27
27
 
28
28
  const parent = this.als.getStore() ?? undefined;
29
29
 
30
+ // Intentional mutation: set defaults on the input object to avoid
31
+ // allocating an intermediate copy. Callers always pass a fresh literal.
30
32
  data.registry ??= new Map();
31
33
  data.context ??= this.createContextId();
32
34
 
@@ -238,6 +238,10 @@ export class EventManager {
238
238
  }
239
239
 
240
240
  const catchErrors = options.catch ?? false;
241
+
242
+ // Logger is captured at compile time. Since compilation happens after
243
+ // start() (on first emit), the logger is already fully configured and
244
+ // won't change afterwards — this is safe.
241
245
  const log = this.log;
242
246
 
243
247
  // Once the first async hook is encountered, all remaining hooks
@@ -836,12 +836,9 @@ describe("KeylessJsonSchemaCodec", () => {
836
836
  const alepha = Alepha.create();
837
837
  const codec = alepha.inject(KeylessJsonSchemaCodec);
838
838
 
839
- // Configure all options
839
+ // Configure options
840
840
  codec.configure({
841
841
  useFunctionCompilation: false,
842
- maxArrayLength: 100,
843
- maxStringLength: 1000,
844
- maxDepth: 10,
845
842
  });
846
843
 
847
844
  // Test that configuration works by encoding/decoding