gemi 0.83.0 → 0.84.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 (272) hide show
  1. package/dist/ai/Agent.d.ts +38 -0
  2. package/dist/ai/Agent.d.ts.map +1 -1
  3. package/dist/ai/generate.d.ts +177 -0
  4. package/dist/ai/generate.d.ts.map +1 -0
  5. package/dist/ai/index.d.ts +2 -0
  6. package/dist/ai/index.d.ts.map +1 -1
  7. package/dist/ai/index.js +11 -11
  8. package/dist/ai/index.js.map +7 -5
  9. package/dist/ai/runtime.d.ts +115 -0
  10. package/dist/ai/runtime.d.ts.map +1 -0
  11. package/dist/ai/types.d.ts +4 -0
  12. package/dist/ai/types.d.ts.map +1 -1
  13. package/dist/app/App.d.ts +0 -5
  14. package/dist/app/App.d.ts.map +1 -1
  15. package/dist/app/index.js +1 -1
  16. package/dist/auth/AuthController.d.ts.map +1 -1
  17. package/dist/auth/accessToken.d.ts +45 -0
  18. package/dist/auth/accessToken.d.ts.map +1 -0
  19. package/dist/auth/config.d.ts +3 -3
  20. package/dist/auth/signInRedirect.d.ts +1 -1
  21. package/dist/bin/gemi.js +2 -33
  22. package/dist/bin/gemi.js.map +6 -6
  23. package/dist/bin/migrate/index.d.ts.map +1 -1
  24. package/dist/bin/migrate/tables.d.ts.map +1 -1
  25. package/dist/bun/plugin.js +1 -1
  26. package/dist/bun/preload.js +1 -1
  27. package/dist/{chunk-7dk4b1fn.js → chunk-159hyeng.js} +2 -2
  28. package/dist/{chunk-7dk4b1fn.js.map → chunk-159hyeng.js.map} +1 -1
  29. package/dist/{chunk-fya5147b.js → chunk-1cebv3h8.js} +2 -2
  30. package/dist/{chunk-fya5147b.js.map → chunk-1cebv3h8.js.map} +1 -1
  31. package/dist/{chunk-gzx3rskd.js → chunk-1evk2pma.js} +4 -4
  32. package/dist/{chunk-gzx3rskd.js.map → chunk-1evk2pma.js.map} +1 -1
  33. package/dist/{chunk-hfxx52vr.js → chunk-1s914cdj.js} +3 -3
  34. package/dist/{chunk-hfxx52vr.js.map → chunk-1s914cdj.js.map} +1 -1
  35. package/dist/chunk-302mkqeq.js +7 -0
  36. package/dist/{chunk-817dxq6w.js.map → chunk-302mkqeq.js.map} +4 -4
  37. package/dist/{chunk-03xrgp1m.js → chunk-3z6wkvwj.js} +2 -2
  38. package/dist/{chunk-03xrgp1m.js.map → chunk-3z6wkvwj.js.map} +1 -1
  39. package/dist/{chunk-2gprnzc3.js → chunk-3zb2ycxj.js} +2 -2
  40. package/dist/{chunk-2gprnzc3.js.map → chunk-3zb2ycxj.js.map} +1 -1
  41. package/dist/{chunk-9146818v.js → chunk-495qwteq.js} +3 -3
  42. package/dist/{chunk-9146818v.js.map → chunk-495qwteq.js.map} +1 -1
  43. package/dist/chunk-49akdtfe.js +17 -0
  44. package/dist/{chunk-rs0xmd64.js.map → chunk-49akdtfe.js.map} +11 -12
  45. package/dist/{chunk-0e5z1x9w.js → chunk-53we503k.js} +2 -2
  46. package/dist/{chunk-0e5z1x9w.js.map → chunk-53we503k.js.map} +3 -3
  47. package/dist/{chunk-q7ngq6c5.js → chunk-57ryyhh3.js} +2 -2
  48. package/dist/{chunk-q7ngq6c5.js.map → chunk-57ryyhh3.js.map} +1 -1
  49. package/dist/{chunk-mc1xsz8j.js → chunk-73dk6k4p.js} +3 -3
  50. package/dist/{chunk-mc1xsz8j.js.map → chunk-73dk6k4p.js.map} +1 -1
  51. package/dist/{chunk-t2htq1v0.js → chunk-82nn71zs.js} +2 -2
  52. package/dist/{chunk-t2htq1v0.js.map → chunk-82nn71zs.js.map} +1 -1
  53. package/dist/{chunk-bwwjkdts.js → chunk-87x692j7.js} +2 -2
  54. package/dist/{chunk-bwwjkdts.js.map → chunk-87x692j7.js.map} +1 -1
  55. package/dist/{chunk-zv7417j0.js → chunk-8mmfpqgs.js} +2 -2
  56. package/dist/{chunk-v0j7spj5.js.map → chunk-8mmfpqgs.js.map} +1 -1
  57. package/dist/{chunk-d2tpgkg2.js → chunk-ah9ajys0.js} +1 -1
  58. package/dist/{chunk-zbhqa2z7.js → chunk-ash9e6fn.js} +2 -2
  59. package/dist/{chunk-zbhqa2z7.js.map → chunk-ash9e6fn.js.map} +1 -1
  60. package/dist/{chunk-mmq47yh3.js → chunk-aztkrzvf.js} +2 -2
  61. package/dist/{chunk-mmq47yh3.js.map → chunk-aztkrzvf.js.map} +1 -1
  62. package/dist/chunk-b9dejyaq.js +6 -0
  63. package/dist/{chunk-cmj9xnbp.js.map → chunk-b9dejyaq.js.map} +2 -2
  64. package/dist/{chunk-actjm3wr.js → chunk-bn9pzgww.js} +2 -2
  65. package/dist/{chunk-actjm3wr.js.map → chunk-bn9pzgww.js.map} +1 -1
  66. package/dist/{chunk-2frgq249.js → chunk-cfvq30n4.js} +2 -2
  67. package/dist/{chunk-2frgq249.js.map → chunk-cfvq30n4.js.map} +1 -1
  68. package/dist/{chunk-egw90hq5.js → chunk-cg4k40zy.js} +2 -2
  69. package/dist/{chunk-egw90hq5.js.map → chunk-cg4k40zy.js.map} +1 -1
  70. package/dist/{chunk-1dgab0qn.js → chunk-d0qwdeza.js} +2 -2
  71. package/dist/{chunk-1dgab0qn.js.map → chunk-d0qwdeza.js.map} +1 -1
  72. package/dist/{chunk-1k783c44.js → chunk-dvpxkzms.js} +2 -2
  73. package/dist/{chunk-1k783c44.js.map → chunk-dvpxkzms.js.map} +1 -1
  74. package/dist/chunk-e43drft2.js +5 -0
  75. package/dist/{chunk-z9x8fx21.js.map → chunk-e43drft2.js.map} +5 -7
  76. package/dist/{chunk-8ndqqsf0.js → chunk-ekppwzyg.js} +2 -2
  77. package/dist/{chunk-8ndqqsf0.js.map → chunk-ekppwzyg.js.map} +1 -1
  78. package/dist/{chunk-3h1pd6ec.js → chunk-en3mtnsg.js} +2 -2
  79. package/dist/{chunk-3h1pd6ec.js.map → chunk-en3mtnsg.js.map} +1 -1
  80. package/dist/{chunk-v8s1dmc2.js → chunk-enf9mdac.js} +2 -2
  81. package/dist/{chunk-v8s1dmc2.js.map → chunk-enf9mdac.js.map} +1 -1
  82. package/dist/{chunk-gppm9gkg.js → chunk-eysexnqb.js} +2 -2
  83. package/dist/{chunk-gppm9gkg.js.map → chunk-eysexnqb.js.map} +1 -1
  84. package/dist/{chunk-06p4zq4m.js → chunk-g6qe6wyb.js} +2 -2
  85. package/dist/{chunk-06p4zq4m.js.map → chunk-g6qe6wyb.js.map} +1 -1
  86. package/dist/{chunk-fpy7m803.js → chunk-gr61ymse.js} +2 -2
  87. package/dist/{chunk-fpy7m803.js.map → chunk-gr61ymse.js.map} +1 -1
  88. package/dist/{chunk-0kpvbnz0.js → chunk-j9wqzemf.js} +2 -2
  89. package/dist/{chunk-0kpvbnz0.js.map → chunk-j9wqzemf.js.map} +1 -1
  90. package/dist/{chunk-9z5g1rf6.js → chunk-jg9eqd3r.js} +1 -1
  91. package/dist/{chunk-6sd7an1r.js → chunk-k2qh3hvd.js} +2 -2
  92. package/dist/{chunk-6sd7an1r.js.map → chunk-k2qh3hvd.js.map} +1 -1
  93. package/dist/{chunk-d2esms7y.js → chunk-kb3xk9r8.js} +2 -2
  94. package/dist/{chunk-d2esms7y.js.map → chunk-kb3xk9r8.js.map} +1 -1
  95. package/dist/{chunk-2c89p8pf.js → chunk-kfavcgv2.js} +2 -2
  96. package/dist/{chunk-2c89p8pf.js.map → chunk-kfavcgv2.js.map} +1 -1
  97. package/dist/{chunk-5krm6p9w.js → chunk-m0zba09s.js} +3 -3
  98. package/dist/{chunk-5krm6p9w.js.map → chunk-m0zba09s.js.map} +1 -1
  99. package/dist/{chunk-wmbpdjvs.js → chunk-m4xw99vm.js} +2 -2
  100. package/dist/{chunk-wmbpdjvs.js.map → chunk-m4xw99vm.js.map} +1 -1
  101. package/dist/{chunk-6c0s1mb7.js → chunk-ng8pp9k2.js} +2 -2
  102. package/dist/{chunk-6c0s1mb7.js.map → chunk-ng8pp9k2.js.map} +1 -1
  103. package/dist/{chunk-zbpgt20r.js → chunk-nvj1z2rs.js} +2 -2
  104. package/dist/{chunk-zbpgt20r.js.map → chunk-nvj1z2rs.js.map} +1 -1
  105. package/dist/{chunk-h2pbrneh.js → chunk-pa0ya991.js} +2 -2
  106. package/dist/{chunk-h2pbrneh.js.map → chunk-pa0ya991.js.map} +1 -1
  107. package/dist/{chunk-a3mgkrb2.js → chunk-pgpqsgzx.js} +1 -1
  108. package/dist/{chunk-sexaj89x.js → chunk-pt59xjfc.js} +2 -2
  109. package/dist/{chunk-sexaj89x.js.map → chunk-pt59xjfc.js.map} +1 -1
  110. package/dist/{chunk-8vnb3hfz.js → chunk-r5e4vpa1.js} +2 -2
  111. package/dist/{chunk-8vnb3hfz.js.map → chunk-r5e4vpa1.js.map} +1 -1
  112. package/dist/{chunk-vxxk4syx.js → chunk-r8nhndzb.js} +2 -2
  113. package/dist/{chunk-vxxk4syx.js.map → chunk-r8nhndzb.js.map} +1 -1
  114. package/dist/{chunk-vax2fp2k.js → chunk-rmv1jp9p.js} +2 -2
  115. package/dist/{chunk-vax2fp2k.js.map → chunk-rmv1jp9p.js.map} +1 -1
  116. package/dist/{chunk-d07y2ddw.js → chunk-rqh2wdhb.js} +2 -2
  117. package/dist/{chunk-d07y2ddw.js.map → chunk-rqh2wdhb.js.map} +1 -1
  118. package/dist/{chunk-9hbwvcxn.js → chunk-rv7da58g.js} +2 -2
  119. package/dist/chunk-rv7da58g.js.map +10 -0
  120. package/dist/{chunk-2y9haf48.js → chunk-tdnfhe7x.js} +3 -3
  121. package/dist/{chunk-2y9haf48.js.map → chunk-tdnfhe7x.js.map} +1 -1
  122. package/dist/chunk-tmwsvf02.js +5 -0
  123. package/dist/{chunk-nc82trtm.js.map → chunk-tmwsvf02.js.map} +1 -1
  124. package/dist/{chunk-0zr926cf.js → chunk-v1nm4tcq.js} +2 -2
  125. package/dist/{chunk-0zr926cf.js.map → chunk-v1nm4tcq.js.map} +1 -1
  126. package/dist/{chunk-mwrh96hx.js → chunk-v27a4se1.js} +3 -3
  127. package/dist/chunk-v27a4se1.js.map +12 -0
  128. package/dist/chunk-vfrrzr10.js +4 -0
  129. package/dist/chunk-vfrrzr10.js.map +10 -0
  130. package/dist/{chunk-s7rhttvd.js → chunk-vmpzg4z5.js} +3 -3
  131. package/dist/{chunk-s7rhttvd.js.map → chunk-vmpzg4z5.js.map} +1 -1
  132. package/dist/{chunk-aecx542w.js → chunk-w099t7zj.js} +2 -2
  133. package/dist/{chunk-aecx542w.js.map → chunk-w099t7zj.js.map} +1 -1
  134. package/dist/chunk-wh728wd6.js +5 -0
  135. package/dist/chunk-wh728wd6.js.map +10 -0
  136. package/dist/{chunk-vqexqkfk.js → chunk-wkdzz0rx.js} +3 -3
  137. package/dist/chunk-wkdzz0rx.js.map +10 -0
  138. package/dist/{chunk-vngyybzh.js → chunk-wsx3j5ws.js} +2 -2
  139. package/dist/{chunk-vngyybzh.js.map → chunk-wsx3j5ws.js.map} +1 -1
  140. package/dist/{chunk-7y6gpg08.js → chunk-wwdaswxh.js} +3 -3
  141. package/dist/{chunk-7y6gpg08.js.map → chunk-wwdaswxh.js.map} +1 -1
  142. package/dist/{chunk-nq2hm5xm.js → chunk-xhha1gb3.js} +2 -2
  143. package/dist/{chunk-nq2hm5xm.js.map → chunk-xhha1gb3.js.map} +1 -1
  144. package/dist/{chunk-dk0kdrkm.js → chunk-yk8s5egf.js} +2 -2
  145. package/dist/{chunk-dk0kdrkm.js.map → chunk-yk8s5egf.js.map} +1 -1
  146. package/dist/{chunk-y7gfg6tj.js → chunk-ys4fejmx.js} +2 -2
  147. package/dist/{chunk-y7gfg6tj.js.map → chunk-ys4fejmx.js.map} +1 -1
  148. package/dist/{chunk-6eprvf4s.js → chunk-z409rk5j.js} +2 -2
  149. package/dist/{chunk-6eprvf4s.js.map → chunk-z409rk5j.js.map} +1 -1
  150. package/dist/{chunk-t6yzarvt.js → chunk-z7442w3q.js} +2 -2
  151. package/dist/{chunk-t6yzarvt.js.map → chunk-z7442w3q.js.map} +1 -1
  152. package/dist/{chunk-v0j7spj5.js → chunk-zfch4da5.js} +2 -2
  153. package/dist/{chunk-zv7417j0.js.map → chunk-zfch4da5.js.map} +1 -1
  154. package/dist/{chunk-f46ntdj3.js → chunk-zp971jp2.js} +3 -3
  155. package/dist/{chunk-f46ntdj3.js.map → chunk-zp971jp2.js.map} +1 -1
  156. package/dist/chunks/{ThemeProvider-BiNFL6l7.js → ThemeProvider-Dn3UREDn.js} +64 -90
  157. package/dist/chunks/ThemeProvider-Dn3UREDn.js.map +1 -0
  158. package/dist/client/ClientRouter.d.ts.map +1 -1
  159. package/dist/client/QueryResource.d.ts +14 -0
  160. package/dist/client/QueryResource.d.ts.map +1 -1
  161. package/dist/client/index.d.ts +0 -2
  162. package/dist/client/index.d.ts.map +1 -1
  163. package/dist/client/index.js +4 -29
  164. package/dist/client/index.js.map +1 -1
  165. package/dist/config/index.js +1 -1
  166. package/dist/console/run.js +2 -2
  167. package/dist/console/run.js.map +1 -1
  168. package/dist/container/index.js +2 -2
  169. package/dist/container/index.js.map +1 -1
  170. package/dist/database/index.js +2 -2
  171. package/dist/database/index.js.map +1 -1
  172. package/dist/email/index.js +2 -2
  173. package/dist/email/index.js.map +1 -1
  174. package/dist/facades/Auth.d.ts +14 -0
  175. package/dist/facades/Auth.d.ts.map +1 -1
  176. package/dist/facades/index.d.ts +0 -1
  177. package/dist/facades/index.d.ts.map +1 -1
  178. package/dist/facades/index.js +2 -2
  179. package/dist/facades/index.js.map +1 -1
  180. package/dist/foundation/Application.d.ts +7 -3
  181. package/dist/foundation/Application.d.ts.map +1 -1
  182. package/dist/foundation/app.d.ts +1 -1
  183. package/dist/foundation/index.js +2 -2
  184. package/dist/foundation/index.js.map +1 -1
  185. package/dist/http/AuthenticationMiddlware.d.ts +4 -3
  186. package/dist/http/AuthenticationMiddlware.d.ts.map +1 -1
  187. package/dist/http/HttpRequest.d.ts.map +1 -1
  188. package/dist/http/index.js +2 -2
  189. package/dist/http/index.js.map +1 -1
  190. package/dist/i18n/dictionaryRuntime.js +2 -2
  191. package/dist/i18n/dictionaryRuntime.js.map +1 -1
  192. package/dist/i18n/index.js +2 -2
  193. package/dist/i18n/index.js.map +1 -1
  194. package/dist/internal/gemiExternals.d.ts +1 -1
  195. package/dist/internal/gemiExternals.d.ts.map +1 -1
  196. package/dist/kernel/Kernel.d.ts +0 -2
  197. package/dist/kernel/Kernel.d.ts.map +1 -1
  198. package/dist/kernel/context.d.ts +3 -4
  199. package/dist/kernel/context.d.ts.map +1 -1
  200. package/dist/kernel/index.js +3 -3
  201. package/dist/kernel/index.js.map +5 -5
  202. package/dist/kernel/providers.d.ts.map +1 -1
  203. package/dist/orm/context.d.ts +1 -2
  204. package/dist/orm/context.d.ts.map +1 -1
  205. package/dist/orm/index.js +2 -2
  206. package/dist/orm/index.js.map +1 -1
  207. package/dist/server/index.js +2 -2
  208. package/dist/server/index.js.map +1 -1
  209. package/dist/services/cron/ScheduleServiceProvider.d.ts +7 -2
  210. package/dist/services/cron/ScheduleServiceProvider.d.ts.map +1 -1
  211. package/dist/services/index.d.ts +0 -3
  212. package/dist/services/index.d.ts.map +1 -1
  213. package/dist/services/index.js +3 -3
  214. package/dist/services/index.js.map +2 -2
  215. package/dist/services/logging/LogManager.d.ts.map +1 -1
  216. package/dist/services/queue/QueueServiceProvider.d.ts +8 -2
  217. package/dist/services/queue/QueueServiceProvider.d.ts.map +1 -1
  218. package/dist/services/queue/work.js +2 -2
  219. package/dist/services/queue/work.js.map +1 -1
  220. package/dist/services/router/ApiRouteDispatcher.d.ts.map +1 -1
  221. package/dist/services/router/globalMiddleware.d.ts +5 -3
  222. package/dist/services/router/globalMiddleware.d.ts.map +1 -1
  223. package/dist/support/ServiceProvider.d.ts +14 -1
  224. package/dist/support/ServiceProvider.d.ts.map +1 -1
  225. package/dist/support/index.d.ts +1 -1
  226. package/dist/support/index.d.ts.map +1 -1
  227. package/dist/support/index.js +2 -2
  228. package/dist/support/index.js.map +1 -1
  229. package/dist/testing/Page.d.ts.map +1 -1
  230. package/dist/testing/index.js +16 -24
  231. package/dist/testing/index.js.map +1 -1
  232. package/package.json +1 -2
  233. package/dist/broadcasting/BroadcastingChannel.d.ts +0 -5
  234. package/dist/broadcasting/BroadcastingChannel.d.ts.map +0 -1
  235. package/dist/broadcasting/index.d.ts +0 -2
  236. package/dist/broadcasting/index.d.ts.map +0 -1
  237. package/dist/broadcasting/index.js +0 -4
  238. package/dist/broadcasting/index.js.map +0 -10
  239. package/dist/chunk-817dxq6w.js +0 -7
  240. package/dist/chunk-9hbwvcxn.js.map +0 -10
  241. package/dist/chunk-cmj9xnbp.js +0 -6
  242. package/dist/chunk-f9mwxne0.js +0 -4
  243. package/dist/chunk-f9mwxne0.js.map +0 -10
  244. package/dist/chunk-fffph77x.js +0 -5
  245. package/dist/chunk-fffph77x.js.map +0 -10
  246. package/dist/chunk-mwrh96hx.js.map +0 -12
  247. package/dist/chunk-nc82trtm.js +0 -5
  248. package/dist/chunk-rs0xmd64.js +0 -17
  249. package/dist/chunk-vqexqkfk.js.map +0 -10
  250. package/dist/chunk-z9x8fx21.js +0 -5
  251. package/dist/chunks/ThemeProvider-BiNFL6l7.js.map +0 -1
  252. package/dist/client/WebsocketContext.d.ts +0 -10
  253. package/dist/client/WebsocketContext.d.ts.map +0 -1
  254. package/dist/client/useBroadcast.d.ts +0 -4
  255. package/dist/client/useBroadcast.d.ts.map +0 -1
  256. package/dist/client/useSubscription.d.ts +0 -5
  257. package/dist/client/useSubscription.d.ts.map +0 -1
  258. package/dist/facades/Broadcast.d.ts +0 -9
  259. package/dist/facades/Broadcast.d.ts.map +0 -1
  260. package/dist/http/BroadcastingRouter.d.ts +0 -8
  261. package/dist/http/BroadcastingRouter.d.ts.map +0 -1
  262. package/dist/services/pubsub/BroadcastManager.d.ts +0 -24
  263. package/dist/services/pubsub/BroadcastManager.d.ts.map +0 -1
  264. package/dist/services/pubsub/BroadcastServiceProvider.d.ts +0 -5
  265. package/dist/services/pubsub/BroadcastServiceProvider.d.ts.map +0 -1
  266. package/dist/services/pubsub/config.d.ts +0 -7
  267. package/dist/services/pubsub/config.d.ts.map +0 -1
  268. package/dist/services/pubsub/types.d.ts +0 -6
  269. package/dist/services/pubsub/types.d.ts.map +0 -1
  270. /package/dist/{chunk-d2tpgkg2.js.map → chunk-ah9ajys0.js.map} +0 -0
  271. /package/dist/{chunk-9z5g1rf6.js.map → chunk-jg9eqd3r.js.map} +0 -0
  272. /package/dist/{chunk-a3mgkrb2.js.map → chunk-pgpqsgzx.js.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{wf as I}from"./chunk-wmbpdjvs.js";import{Cf as A,Df as U,yf as W,zf as S}from"./chunk-vqexqkfk.js";import{Zf as C}from"./chunk-06p4zq4m.js";import{sg as E}from"./chunk-fffph77x.js";import{vg as N}from"./chunk-fpy7m803.js";class K{table;sql;dialect;connection;busyTimeout;configured;constructor(z,G={}){let V=G.table??"gemi_jobs";if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(V))throw Error(`The queue table name "${V}" is not a plain identifier. Use letters, digits and underscores.`);let Y=G.busyTimeout??1000;if(!Number.isInteger(Y)||Y<0)throw Error(`The queue's busyTimeout must be a whole number of milliseconds, 0 or more; got ${Y}.`);this.table=V,this.sql=z.sql,this.dialect=z.dialect,this.connection=z.name,this.busyTimeout=Y}configure(){if(this.dialect!=="sqlite"||this.busyTimeout===0)return Promise.resolve();return this.configured??=(async()=>{let[z]=await this.sql.unsafe("PRAGMA busy_timeout");if(Number(z?.timeout??0)!==0)return;await this.sql.unsafe(`PRAGMA busy_timeout = ${this.busyTimeout}`)})().catch((z)=>{throw this.configured=void 0,z}),this.configured}async createTable(){await this.configure();for(let z of R(this.dialect,this.table))await this.sql.unsafe(z)}enqueue(z){let G=this.transaction(),V=this.insert(G??this.sql,z);if(G)U(V);return V}async insert(z,{name:G,args:V,delayMs:Y=0,id:Z=Bun.randomUUIDv7()}){await this.configure();let $=this.now(z);return await z`
2
+ import{rf as W,sf as S,vf as A,wf as U}from"./chunk-wkdzz0rx.js";import{Sf as C}from"./chunk-g6qe6wyb.js";import{bg as I}from"./chunk-m4xw99vm.js";import{mg as E}from"./chunk-wh728wd6.js";import{pg as N}from"./chunk-gr61ymse.js";class K{table;sql;dialect;connection;busyTimeout;configured;constructor(z,G={}){let V=G.table??"gemi_jobs";if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(V))throw Error(`The queue table name "${V}" is not a plain identifier. Use letters, digits and underscores.`);let Y=G.busyTimeout??1000;if(!Number.isInteger(Y)||Y<0)throw Error(`The queue's busyTimeout must be a whole number of milliseconds, 0 or more; got ${Y}.`);this.table=V,this.sql=z.sql,this.dialect=z.dialect,this.connection=z.name,this.busyTimeout=Y}configure(){if(this.dialect!=="sqlite"||this.busyTimeout===0)return Promise.resolve();return this.configured??=(async()=>{let[z]=await this.sql.unsafe("PRAGMA busy_timeout");if(Number(z?.timeout??0)!==0)return;await this.sql.unsafe(`PRAGMA busy_timeout = ${this.busyTimeout}`)})().catch((z)=>{throw this.configured=void 0,z}),this.configured}async createTable(){await this.configure();for(let z of R(this.dialect,this.table))await this.sql.unsafe(z)}enqueue(z){let G=this.transaction(),V=this.insert(G??this.sql,z);if(G)U(V);return V}async insert(z,{name:G,args:V,delayMs:Y=0,id:Z=Bun.randomUUIDv7()}){await this.configure();let $=this.now(z);return await z`
3
3
  INSERT INTO ${this.name(z)}
4
4
  (id, name, payload, status, attempts, available_at, created_at, updated_at)
5
5
  VALUES
@@ -137,6 +137,6 @@ import{wf as I}from"./chunk-wmbpdjvs.js";import{Cf as A,Df as U,yf as W,zf as S}
137
137
  }
138
138
  };
139
139
  `],"worker.ts"),Z=URL.createObjectURL(Y);return new Worker(Z)}async function T(z,G){let V=M();return V.postMessage({jobName:z,args:G}),await new Promise((Y,Z)=>{V.onmessage=($)=>{let B=$.data;if("error"in B)Z(B.error);else Y(B.result)}})}var D=new P("gemi.queue"),k=60000;class x{static token="queue";jobs={};config;driver;application;inFlight=new Map;state="idle";looping=!1;claiming;woken=!1;claimFailures=0;resume;unsubscribe;heartbeatTimer;releasedNames=new Set;constructor(z={},G={}){this.config=I(_(),z),this.application=G.application,this.driver=q(this.config.driver,this.application),this.useJobs(this.config.jobs)}useJobs(z){this.config.jobs=z,this.jobs={};for(let G of z)this.claim(G)}registerJob(z){this.config.jobs=[...this.config.jobs,z],this.claim(z)}claim(z){if(this.jobs[z.name]){console.error(`Two queued jobs are named "${z.name}" \u2014 the first is registered `+"and this one is not, so dispatching either would have run one of them. A class name is the queue's key, so only one job can hold it. Rename one.");return}this.jobs[z.name]=z}get registeredJobs(){return[...this.config.jobs]}dispatchJob(z,G){if(this.jobs[z])return new this.jobs[z]().run(JSON.parse(G))}push(z,G,V={}){let Y=this.driver.joinsTransaction?.()===!0;if(!Y){let Z=Bun.randomUUIDv7();if(A(()=>this.record(z,G,{id:Z,reportFailure:!0,committed:!0}).then(()=>{},()=>{})))return Promise.resolve(Z)}return this.record(z,G,{reportFailure:V.reportFailure,joins:Y})}record(z,G,V){let Y=this.driver.enqueue({name:z.name,args:G,...V.id===void 0?{}:{id:V.id}});this.startIfIdle();let Z=()=>!this.driver.subscribe&&this.state==="running"&&this.wake(),$=V.joins===!0&&A(Z);return Y.then(()=>$||Z(),(B)=>{if(V.reportFailure===!1)return;console.error(`[gemi] The queue driver could not record ${z.name}`+(V.committed?", which was held until its transaction committed. The transaction stays committed; the job did not run and will not be retried.":", so it did not run and will not be retried."),B)}),Y}async retryDead(z){if(!this.driver.retryDead)throw Error("This queue's driver keeps nothing of a dead-lettered job, so there is nothing to retry. The database driver keeps them.");let G=await this.driver.retryDead(z);if(G)this.claimSoon();return G}startIfIdle(){if(this.state==="idle"&&(!this.durable||this.mayClaimHere()))this.start()}claimSoon(){if(this.startIfIdle(),!this.driver.subscribe&&this.state==="running")this.wake()}start(){if(this.state==="running")return;if(this.state="running",this.durable&&this.application&&this.mayClaimHere()&&!v())globalThis.__gemiDevQueue=this;if(this.unsubscribe=this.driver.subscribe?.(()=>this.wake()),this.looping)return this.wake();D.runInAsyncScope(()=>void this.loop())}async drain(z=1/0){if(this.state="stopped",globalThis.__gemiDevQueue===this)globalThis.__gemiDevQueue=void 0;this.unsubscribe?.(),this.unsubscribe=void 0,this.wake();let G,V=new Promise((Z)=>{if(z!==1/0)G=setTimeout(Z,z)}),Y=(async()=>{await this.claiming?.catch(()=>{}),await Promise.allSettled([...this.inFlight.values()].map((Z)=>Z.done))})();return await Promise.race([Y,V]),clearTimeout(G),{unfinished:[...this.inFlight.values()].map((Z)=>({...Z.job}))}}stop(){return this.drain(0)}get running(){return this.inFlight.size}async loop(){this.looping=!0;try{await this.claimWhileRunning()}finally{this.looping=!1}}async claimWhileRunning(){while(this.state==="running"){let z=this.durable&&N()?0:this.config.concurrency-this.inFlight.size;if(z>0){this.woken=!1;let G=this.driver.claim(z,{...this.lease(),registered:{names:Object.keys(this.jobs),graceMs:this.config.unknownJobGrace}});this.claiming=G;let V=[];try{V=await G,this.claimFailures=0}catch(Y){this.claimFailures++,console.error(`The queue could not claim jobs from its driver; it will try again in ${this.retryDelay()}ms.`,Y)}finally{this.claiming=void 0}for(let Y of V)this.execute(Y);if(V.length===z)continue;if(this.woken&&this.inFlight.size<this.config.concurrency)continue}await this.sleep()}}sleep(){return new Promise((z)=>{let G,V=this.claimFailures>0?this.retryDelay():this.driver.subscribe?void 0:this.config.pollInterval;if(V!==void 0)G=setTimeout(()=>this.wake(),V),G.unref?.();this.resume=()=>{clearTimeout(G),z()}})}retryDelay(){let z=Math.min(Math.max(0,this.claimFailures-1),30);return Math.min(this.config.pollInterval*2**z,k)}wake(){this.woken=!0;let z=this.resume;this.resume=void 0,z?.()}get durable(){return!(this.driver instanceof X)}mayClaimHere(){return!this.application||g()}lease(){return{visibilityTimeoutMs:this.config.visibilityTimeout}}execute(z){let G=`${z.id}:${z.attempt}`,V=()=>this.run(z),Y=(this.application?E.run(this.application,V):V()).catch((Z)=>{console.error(`The queue could not record the outcome of ${z.name}.`,Z)}).finally(()=>{this.inFlight.delete(G),this.wake()});this.inFlight.set(G,{job:z,done:Y}),this.heartbeat()}heartbeat(){let z=this.driver;if(!z.heartbeat||this.heartbeatTimer)return;this.heartbeatTimer=setInterval(()=>{if(this.inFlight.size===0){clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0;return}let G=[...this.inFlight.values()].map((V)=>V.job);z.heartbeat(G,this.lease()).catch((V)=>{console.error("The queue could not extend its job leases.",V)})},Math.max(1,Math.floor(this.config.visibilityTimeout/3))),this.heartbeatTimer.unref?.()}async run(z){let G=this.jobs[z.name];if(!G){let Z=Date.now()-z.createdAt;if(this.durable&&Z<this.config.unknownJobGrace){if(!this.releasedNames.has(z.name))this.releasedNames.add(z.name),console.error(`Left a queued "${z.name}" for another replica: nothing is registered here under that name. It is dead-lettered if no replica has run it within unknownJobGrace (${this.config.unknownJobGrace}ms) of its dispatch.`);await this.driver.release(z,{retryInMs:Math.round(this.config.pollInterval*(1+Math.random()))});return}console.error(`Dropped a queued job: nothing is registered under the name "${z.name}". If the class exists, it was not `+"discovered \u2014 check that it is under the queue slice's jobsDir "+"(app/jobs by default), or list it in app/config/queue.ts."),await this.driver.fail(z,{error:`No job is registered under the name "${z.name}".`,retryInMs:null});return}let V;try{V=new G}catch(Z){console.error(`Dropped a queued ${z.name}: it could not be constructed.`,Z),await this.driver.fail(z,{error:`The job could not be constructed: ${String(Z)}`,retryInMs:null});return}let Y;try{Y=JSON.parse(z.args)}catch(Z){console.error(`Dropped a queued ${z.name}: its arguments are not JSON.`,Z),await this.driver.fail(z,{error:`The arguments are not JSON: ${String(Z)}`,retryInMs:null});return}if(z.attempt>Math.max(1,V.maxAttempts)){let Z=Error(`${z.name} was claimed for attempt ${z.attempt} of ${V.maxAttempts}: an earlier attempt never finished, most likely because the process running it exited. Dead-lettered without running it again.`);L(`${z.name}.onDeadletter`,()=>V.onDeadletter(Z,...Y)),await this.driver.fail(z,{error:Z.message,retryInMs:null});return}try{let Z=await(V.worker?T(z.name,z.args):V.run(...Y));V.onSuccess(Z,...Y)}catch(Z){let $=Z,B=String($?.stack??$);if(L(`${z.name}.onFail`,()=>V.onFail($,...Y)),z.attempt>=V.maxAttempts)L(`${z.name}.onDeadletter`,()=>V.onDeadletter($,...Y)),await this.driver.fail(z,{error:B,retryInMs:null});else await this.driver.fail(z,{error:B,retryInMs:f(V.backoff,z.attempt)});return}await this.driver.complete(z)}}function L(z,G){try{G()}catch(V){console.error(`${z} threw; the job's claim was ended anyway.`,V)}}function v(){return Bun.env.NODE_ENV==="production"}function g(){if(!Q)return!1;if(h())return!0;return process.env.ROOT_DIR!==void 0&&!y()}function y(z=process.env){return(z.GEMI_QUEUE_CLAIM??"").trim().toLowerCase()==="off"}var O=Symbol.for("gemi.queue.worker");function o(z=!0){globalThis[O]=z}function h(){return globalThis[O]===!0}function f(z,G){let V=Array.isArray(z)?z[Math.min(G,z.length)-1]:z;return Math.max(0,V??0)}function q(z,G){if(z==="memory")return new X;if(z==="database"||typeof z==="function"){if(!G&&(z==="database"||z.length>0))throw Error("The queue driver needs the application it belongs to, and this QueueManager was built without one. Pass { application }.");if(z==="database")return new K(G.make(C));return z(G)}if(typeof z==="string")throw Error(`Unknown queue driver "${z}". The queue slice's driver is "memory", "database", a QueueDriver, or a function returning one.`);return z}
140
- export{K as Yb,j as Zb,_ as _b,X as $b,x as ac,g as bc,y as cc,o as dc,h as ec};
140
+ export{K as Vb,j as Wb,_ as Xb,X as Yb,x as Zb,g as _b,y as $b,o as ac,h as bc};
141
141
 
142
- //# debugId=F0D1B1CBA0387DB764756E2164756E21
142
+ //# debugId=6B52A7598A2A8F5E64756E2164756E21
@@ -8,6 +8,6 @@
8
8
  "import { AsyncResource } from \"node:async_hooks\";\nimport { isMainThread } from \"node:worker_threads\";\n\nimport type { Application } from \"../../foundation/Application\";\nimport { DatabaseManager } from \"../../database/DatabaseManager\";\nimport { kernelContext } from \"../../kernel/context\";\nimport { deferUntilCommit } from \"../../orm/context\";\nimport { isShuttingDown } from \"../../server/shutdown\";\nimport { DatabaseQueueDriver } from \"./DatabaseQueueDriver\";\nimport { Job } from \"./Job\";\nimport { queueConfigDefaults, type QueueConfig } from \"./config\";\nimport { MemoryQueueDriver } from \"./MemoryQueueDriver\";\nimport type { ClaimOptions, ClaimedJob, QueueDriver } from \"./QueueDriver\";\nimport { withDefaults } from \"../../support/withDefaults\";\n\n/**\n * The thread a `worker = true` job runs in.\n *\n * The `await` on `dispatchJob` is load-bearing and its absence was a hang.\n * `postMessage` structured-clones its argument and a Promise is not cloneable,\n * so an un-awaited `dispatchJob` posted the pending promise, threw\n * `DataCloneError` inside this handler, and posted nothing at all. `runInWorker`\n * then never settled: `run` below never returned, its concurrency slot was\n * never decremented, and neither the retry path nor `onDeadletter` ever fired —\n * after `concurrency` such jobs the queue sits at its limit forever, with no\n * error anywhere. Any job whose `run` is `async` hit it, which is every job\n * that touches IO; a queued listener hits it unconditionally, because the\n * synthetic job's `run` awaits `handle`.\n *\n * The await earns two more things. A rejecting job now reaches the `catch` and\n * comes back as `{error}`, where the queue's ordinary retry-then-dead-letter\n * path can have it, instead of being lost with the promise. And `destroy()` now\n * runs after the job rather than under it, so the cloned kernel — its database\n * connections included — outlives the work it was cloned for.\n */\nfunction createWorker() {\n const APP_DIR = process.env.APP_DIR;\n const ROOT_DIR = process.env.ROOT_DIR;\n\n const appPath =\n process.env.NODE_ENV === \"production\"\n ? `${ROOT_DIR}/dist/server/bootstrap.mjs`\n : `${APP_DIR}/bootstrap.ts`;\n\n const file = new File(\n [\n `\n import { app } from \"${appPath}\"\n self.onmessage = async (event) => {\n const clone = app.clone()\n let result = null;\n let error = null;\n try {\n result = await clone.dispatchJob(event.data.jobName, event.data.args)\n } catch (err) {\n error = err\n }\n clone.destroy()\n if(error) {\n self.postMessage({error});\n } else {\n self.postMessage({result});\n }\n };\n `,\n ],\n \"worker.ts\",\n );\n const url = URL.createObjectURL(file);\n return new Worker(url);\n}\n\n// TODO: terminate worker after the job is done\nasync function runInWorker(jobName: string, args: string) {\n const worker = createWorker();\n worker.postMessage({ jobName, args });\n return await new Promise((resolve, reject) => {\n worker.onmessage = (e) => {\n const data = e.data;\n if (\"error\" in data) {\n reject(data.error);\n } else {\n resolve(data.result);\n }\n };\n });\n}\n\n/**\n * The async context every job runs in: the one this module was evaluated in,\n * which is boot, outside any request.\n *\n * The worker loop is long-lived and started lazily, by the first dispatch, and\n * an async function keeps the context it was started in across every `await`.\n * Started from a request, it would run every later job — dispatched by any\n * request at all — inside the first one's `RequestContext`, and with its ORM\n * transaction handle if it had one open: one user's identity leaking into\n * another's work. Captured here, where no request exists, and entered by `start()`, a job\n * sees no request at all; the Application is entered separately, per job.\n */\nconst bootScope = new AsyncResource(\"gemi.queue\");\n\n/**\n * The longest the loop waits between retries while `claim` keeps rejecting.\n *\n * Long enough that a database which is properly down is not asked once a\n * second by every worker process for as long as it stays down, short enough\n * that the queue is claiming again within a minute of it coming back.\n */\nconst maxClaimBackoff = 60_000;\n\ndeclare global {\n /**\n * The queue loop a `gemi dev` server is running over a driver that outlives\n * the process, kept where a `bun --hot` reload cannot lose it. A reload\n * re-evaluates every module and boots a new application, but the previous\n * application's loop is a live closure and keeps claiming — from the same\n * table, with the code it was loaded with. This is how the next\n * application finds it to stop it; see `startClaimingIfServing`.\n *\n * Typed by what is called on it, not as `QueueManager`: after a reload the\n * one held here is an instance of the previous module graph's class.\n */\n var __gemiDevQueue: { stop(): Promise<unknown> } | undefined;\n}\n\n/** What `drain` could not wait out. */\nexport type DrainResult = {\n /**\n * Jobs still running when the timeout elapsed. They keep running, and keep\n * their leases, until they settle or the process exits; with a driver that\n * outlives the process, an exit leaves them to be reclaimed once their lease\n * runs out. Waiting jobs are not listed — they were never taken, and are\n * wherever the driver keeps them.\n */\n unfinished: ClaimedJob[];\n};\n\nexport class QueueManager {\n static token = \"queue\";\n\n jobs: Record<string, new () => Job> = {};\n\n readonly config: Required<QueueConfig>;\n readonly driver: QueueDriver;\n\n private readonly application: Application | undefined;\n /**\n * Keyed by claim, `id:attempt`, not by job id. A lease that lapses while\n * its job is still running here — heartbeats failing through a database\n * blip, or an event loop blocked past the visibility timeout — lets this\n * same process claim the job again. Both runs are then really running, so\n * both take a slot. Keyed by id alone, the second claim overwrote the first\n * and the first one's `finally` then deleted it: the live run stopped being\n * counted, drained or heartbeated, so its lease lapsed in turn and the job\n * was claimed again into a slot that was never free.\n */\n private readonly inFlight = new Map<\n string,\n { job: ClaimedJob; done: Promise<void> }\n >();\n private state: \"idle\" | \"running\" | \"stopped\" = \"idle\";\n private looping = false;\n private claiming: Promise<unknown> | undefined;\n private woken = false;\n /** Consecutive `claim` rejections; see `sleep`. Cleared by a claim that returns. */\n private claimFailures = 0;\n private resume: (() => void) | undefined;\n private unsubscribe: (() => void) | undefined;\n private heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n /** Unknown names already reported as left for another replica; see `run`. */\n private readonly releasedNames = new Set<string>();\n\n /**\n * `application` is entered around every job, so `app()` inside one resolves\n * to it rather than to whichever application happens to be the static\n * fallback. The provider always passes it; a manager built bare, as the unit\n * tests do, runs jobs with no application entered.\n */\n constructor(\n config: QueueConfig = {},\n options: { application?: Application } = {},\n ) {\n this.config = withDefaults(queueConfigDefaults(), config);\n this.application = options.application;\n this.driver = resolveDriver(this.config.driver, this.application);\n this.useJobs(this.config.jobs);\n }\n\n /**\n * Replaces the registered set, for the provider to hand over what it found\n * under `app/jobs`.\n *\n * This exists because the two phases disagree about when the answer is\n * knowable. The manager is constructed in `register()`, which is synchronous\n * and must resolve nothing; reading a directory and importing what is in it is\n * neither. So the manager is built from whatever the config slice declared —\n * nothing, when the app left `jobs` out — and the discovered set arrives in\n * `boot()`.\n *\n * The consequence worth knowing: anything that constructs an application and\n * skips phase two sees an empty registry, and every dispatch against an empty\n * registry is dropped — loudly on stderr, but after `Job.dispatch` has already\n * returned, so no caller finds out. On a durable driver not even that is\n * immediate: the job is left for another replica, and the stderr line comes\n * only once `unknownJobGrace` has passed. An app that lists its jobs explicitly is\n * unaffected, because that list is already in place by the end of `register()`.\n */\n useJobs(jobs: Array<new () => Job>) {\n this.config.jobs = jobs;\n\n // Built one at a time rather than by `Object.fromEntries`, which resolves a\n // repeated key by keeping the last and saying nothing.\n //\n // Two classes with one name is the worst failure in this subsystem, and it\n // is worse than the dropped dispatch the rest of this file is about: the\n // registry is keyed by class name, a dispatch carries a class name, so\n // `SendEmail.dispatch(...)` on the one under `app/jobs/auth` would run the\n // body of the one under `app/jobs/billing`. Nothing is dropped and nothing\n // errors — the wrong work happens and reports success.\n //\n // Discovery is what makes it ordinary. A hand-written list forces an import\n // alias in one visible file the moment two names clash; a directory walk\n // does not, and `auth/SendEmail.ts` beside `billing/SendEmail.ts` is a\n // perfectly natural thing to write. So the first claim wins and the second\n // is refused out loud — the same rule `Scheduler.start` applies to a cron\n // name, and the reverse of the silent last-wins this replaces.\n this.jobs = {};\n for (const job of jobs) {\n this.claim(job);\n }\n }\n\n /**\n * Registers one more job beside whatever `useJobs` already took.\n *\n * This exists for the queued-listener adapter, which registers a synthetic\n * job per queued listener from `EventServiceProvider.boot()` — after the\n * queue's own `boot()` has filled the registry. `useJobs` cannot serve that\n * caller: it *replaces* the registry, so a second call would discard every\n * job the app wrote and leave the queue holding listeners alone. Reading\n * `registeredJobs` back, concatenating and calling `useJobs` again avoids\n * that and is still the wrong shape — it re-runs the collision check over\n * jobs that already passed it, so a duplicate the author has already been\n * told about is reported a second time on every boot.\n *\n * Same rule as `useJobs`, deliberately: the first claim on a name wins and\n * the second is refused out loud. And recorded in `config.jobs` either way,\n * so `registeredJobs` keeps reporting everything the manager was handed\n * rather than what it accepted — a refused job is visible to a test there.\n *\n * A new array rather than a `push`, because `useJobs` keeps the caller's\n * array by reference and appending to it would edit the config slice or the\n * discovered list under whoever else is holding it.\n */\n registerJob(job: new () => Job) {\n this.config.jobs = [...this.config.jobs, job];\n this.claim(job);\n }\n\n /**\n * Puts one job in the registry, or refuses it because the name is taken.\n *\n * The rule and the reason are in `useJobs` above; this is only the shape both\n * entry points share, so that a job arriving one at a time cannot be admitted\n * on terms the batch would have refused.\n */\n private claim(job: new () => Job) {\n if (this.jobs[job.name]) {\n console.error(\n `Two queued jobs are named \"${job.name}\" — the first is registered ` +\n `and this one is not, so dispatching either would have run one of ` +\n `them. A class name is the queue's key, so only one job can hold ` +\n `it. Rename one.`,\n );\n return;\n }\n this.jobs[job.name] = job;\n }\n\n /**\n * What the manager was handed, discovered or declared.\n *\n * The registry is keyed by name, and a name is exactly what a dispatch\n * carries, so \"is this job registered?\" is a question with a silent wrong\n * answer — `run()` drops an unknown name long after the caller moved on.\n * This is where a test asks it out loud.\n *\n * It reports what came in, not what the registry accepted, so a name claimed\n * twice appears twice here — deliberately, the same way `Scheduler.jobs`\n * does. A test walking this should see the collision rather than have it\n * tidied away. A copy, so that walk cannot edit the registry underneath it.\n */\n get registeredJobs(): ReadonlyArray<new () => Job> {\n return [...this.config.jobs];\n }\n\n dispatchJob(jobName: string, args: string) {\n if (this.jobs[jobName]) {\n const job = new this.jobs[jobName]();\n return job.run(JSON.parse(args));\n }\n }\n\n /**\n * Queues a job and resolves to its id once the driver has recorded it, then\n * makes sure the worker loop is running — unless `drain` stopped it, in which\n * case the job waits in the driver for whichever process claims next. With\n * the memory driver that is nobody; see `drain`. A durable driver's job also\n * waits there when this process does not claim: it is not a server, or it is\n * one started with `GEMI_QUEUE_CLAIM=off`; see `claimsInThisProcess`.\n *\n * Inside an open ORM transaction the job belongs to the transaction. A\n * driver that can write it on the transaction does (`joinsTransaction`);\n * for any other, it is held and recorded once the transaction commits, and\n * never if it rolls back. Either way no claimer can see the job before the\n * data it was dispatched about exists. A held dispatch resolves at once, to\n * the id the job will be recorded under: the transaction does not commit\n * until its callback returns, so a caller awaiting a promise that waited for\n * the commit would never return.\n */\n push(\n job: new () => Job,\n args: string,\n options: {\n /**\n * Whether a driver that cannot record the job is reported from here.\n * On by default, because the usual caller is a fire-and-forget\n * `Job.dispatch(...)` whose promise nobody reads. A caller with\n * something better to say — `EventManager`, which knows the event and\n * the listener — turns it off and says that instead. A held dispatch is\n * reported here whatever this says, because its promise has already\n * resolved and the caller has nothing left to catch.\n */\n reportFailure?: boolean;\n } = {},\n ): Promise<string> {\n // Asked before anything is written, and in the caller's async context,\n // which is where the transaction is. The held branch is the fallback\n // rather than the rule because it loses the job to a crash between the\n // commit and the enqueue; written on the transaction, the job commits\n // with the rows or not at all.\n const joins = this.driver.joinsTransaction?.() === true;\n if (!joins) {\n // `deferUntilCommit` is the ORM's commit hook, and the same one an\n // `afterCommit` event waits on: a savepoint that rolls back takes its\n // held dispatches with it, and the callback runs outside the\n // transaction, so the enqueue cannot be pulled back into it.\n const id = Bun.randomUUIDv7();\n const held = deferUntilCommit(() =>\n // Awaited, so the transaction's own promise waits for the enqueue and\n // a script that exits after its last transaction does not exit under\n // it. The rejection is swallowed only because `record` has already\n // reported it; rethrown, the drain would report it a second time.\n this.record(job, args, {\n id,\n reportFailure: true,\n committed: true,\n }).then(\n () => {},\n () => {},\n ),\n );\n if (held) return Promise.resolve(id);\n }\n return this.record(job, args, {\n reportFailure: options.reportFailure,\n joins,\n });\n }\n\n /** `push`, once it is known that the job is recorded now. */\n private record(\n job: new () => Job,\n args: string,\n options: {\n id?: string;\n reportFailure?: boolean;\n /** Written on the caller's open transaction; see `push`. */\n joins?: boolean;\n /** Held until a transaction committed; changes only the error line. */\n committed?: boolean;\n },\n ): Promise<string> {\n const id = this.driver.enqueue({\n name: job.name,\n args,\n ...(options.id === undefined ? {} : { id: options.id }),\n });\n // A driver that outlives the process is shared with every other one, so\n // a script or console command that dispatches would otherwise claim up to\n // `concurrency` of the table's jobs — other replicas' included — and exit\n // under them, costing each an attempt and a lease's wait. There the job\n // waits in the driver for a server or a worker. A manager built by hand,\n // with no application, is its caller's to run and keeps starting.\n this.startIfIdle();\n // A driver without `subscribe` is only polled, so without the wake a job\n // dispatched here would wait up to `pollInterval` in a queue with room.\n // A spurious wake just claims nothing.\n //\n // A job written on the caller's transaction is not claimable until that\n // commits, so its wake waits for the commit too — woken now, the loop\n // would claim nothing and then sleep a whole `pollInterval` past it.\n // Registered here, synchronously, because the commit hook is found\n // through the caller's async context, and this is the one place that is\n // certainly still current.\n const wake = () =>\n !this.driver.subscribe && this.state === \"running\" && this.wake();\n const wakeAtCommit = options.joins === true && deferUntilCommit(wake);\n\n // The rejection is reported here unless the caller says it will do it\n // itself, and whatever the driver is. It used to depend on both, and was\n // lost either way: a polled driver got an empty rejection arm, which marks\n // `id` handled — and `id` is what `push` returns — so a fire-and-forget\n // `SendReceiptJob.dispatch(...)` whose INSERT failed (a failover, a pool\n // timeout, a table not migrated yet) produced no unhandled rejection and\n // no line anywhere, and the job simply never ran. A subscribing driver got\n // no arm at all, so the same failure surfaced as a bare unhandled\n // rejection. A caller that awaits still gets the rejection either way and\n // can still decide what to do about it.\n id.then(\n () => wakeAtCommit || wake(),\n (error: unknown) => {\n if (options.reportFailure === false) return;\n console.error(\n `[gemi] The queue driver could not record ${job.name}` +\n (options.committed\n ? `, which was held until its transaction committed. The ` +\n `transaction stays committed; the job did not run and will ` +\n `not be retried.`\n : `, so it did not run and will not be retried.`),\n error,\n );\n },\n );\n return id;\n }\n\n /**\n * Runs a dead-lettered job again, from attempt 1 with its whole\n * `maxAttempts`, and resolves to whether a dead job was found under `id`.\n * `false` for an id that is waiting, running, finished or unknown: only a\n * dead job is brought back, so this cannot restart one that is running\n * somewhere.\n *\n * The job is claimed the way a dispatch's is. On a server it is run here as\n * soon as there is room; from a console command it waits in the driver for\n * a server or a worker, which with a polling driver means up to\n * `pollInterval`.\n *\n * Refused for a driver without `retryDead`. The memory driver keeps nothing\n * of a dead job, so there is no id it could bring back, and resolving\n * `false` would read as \"no such job\" to someone holding an id they just saw\n * in a log.\n */\n async retryDead(id: string): Promise<boolean> {\n if (!this.driver.retryDead) {\n throw new Error(\n `This queue's driver keeps nothing of a dead-lettered job, so there ` +\n `is nothing to retry. The database driver keeps them.`,\n );\n }\n const found = await this.driver.retryDead(id);\n if (found) this.claimSoon();\n return found;\n }\n\n /**\n * Starts the loop unless `drain` stopped it or this process should leave a\n * shared driver's jobs to a server — the rule `push` explains.\n */\n private startIfIdle() {\n if (this.state === \"idle\" && (!this.durable || this.mayClaimHere())) {\n this.start();\n }\n }\n\n /**\n * For a job the driver has just made claimable: start the loop, or wake a\n * running one that only polls, as `push` does for a dispatch.\n */\n private claimSoon() {\n this.startIfIdle();\n if (!this.driver.subscribe && this.state === \"running\") this.wake();\n }\n\n /**\n * Starts claiming. Idempotent, and called by the first `push`, so an app\n * does not need to; it is public for a process that should run jobs it\n * never dispatched — ones a driver kept across a restart — and for resuming\n * after `drain`.\n */\n start() {\n if (this.state === \"running\") return;\n this.state = \"running\";\n // Only a development server's loop over a shared driver: a memory queue\n // is only ever fed by its own application, and a hand-built manager or a\n // test's is its caller's to stop.\n if (this.durable && this.application && this.mayClaimHere() && !isProduction()) {\n globalThis.__gemiDevQueue = this;\n }\n this.unsubscribe = this.driver.subscribe?.(() => this.wake());\n // A loop a `drain` has not yet seen off picks the new state up itself;\n // starting a second would claim twice per wake.\n if (this.looping) return this.wake();\n bootScope.runInAsyncScope(() => void this.loop());\n }\n\n /**\n * Stops claiming, waits up to `timeoutMs` for the jobs already running, and\n * reports the ones that did not finish.\n *\n * Nothing is cancelled — a job has no way to be told — so an unfinished job\n * keeps running after this resolves. What happens to it then is the\n * driver's: the memory driver loses it with the process, along with every\n * job still waiting; one that outlives the process lets another claim it\n * once the lease runs out.\n *\n * A later `push` records its job but does not restart the loop. `start()`\n * does.\n */\n async drain(timeoutMs = Infinity): Promise<DrainResult> {\n this.state = \"stopped\";\n if (globalThis.__gemiDevQueue === this) globalThis.__gemiDevQueue = undefined;\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n this.wake();\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<void>((resolve) => {\n if (timeoutMs !== Infinity) timer = setTimeout(resolve, timeoutMs);\n });\n // The claim in progress first, because what it returns is run: those jobs\n // are leased to this process already, and handing them back would cost\n // each of them an attempt it never made.\n const settled = (async () => {\n await this.claiming?.catch(() => {});\n await Promise.allSettled([...this.inFlight.values()].map((e) => e.done));\n })();\n await Promise.race([settled, deadline]);\n clearTimeout(timer);\n\n return {\n unfinished: [...this.inFlight.values()].map((e) => ({ ...e.job })),\n };\n }\n\n /** `drain(0)`: stop claiming, and report what is running without waiting. */\n stop(): Promise<DrainResult> {\n return this.drain(0);\n }\n\n /** How many jobs this process is running right now. */\n get running(): number {\n return this.inFlight.size;\n }\n\n /**\n * Claims while there is room, runs what it claims, and otherwise sleeps\n * until something changes: a job finishing frees a slot, or the driver's\n * `subscribe` says there is work. A driver without `subscribe` is polled\n * every `pollInterval` instead. This replaces a one-second timer that\n * spun while the queue was full.\n *\n * `woken` records a wake that arrived while a claim was in flight, when\n * there was nothing yet to resume; without it that job would wait for the\n * next unrelated wake.\n */\n private async loop() {\n this.looping = true;\n try {\n await this.claimWhileRunning();\n } finally {\n this.looping = false;\n }\n }\n\n private async claimWhileRunning() {\n while (this.state === \"running\") {\n // Once the server has been told to stop, a driver that outlives the\n // process gets nothing new taken from it: a job claimed now would likely\n // be cut off by the exit, and cost an attempt and a lease's wait, when\n // another replica can run it instead. The memory driver keeps claiming\n // until the provider's `drain()` stops it, because nobody else can run\n // its jobs — one waiting at the signal, or dispatched by a request\n // still draining, is run here or not at all.\n const room = this.durable && isShuttingDown()\n ? 0\n : this.config.concurrency - this.inFlight.size;\n\n if (room > 0) {\n this.woken = false;\n const claim = this.driver.claim(room, {\n ...this.lease(),\n registered: {\n names: Object.keys(this.jobs),\n graceMs: this.config.unknownJobGrace,\n },\n });\n this.claiming = claim;\n let claimed: ClaimedJob[] = [];\n try {\n claimed = await claim;\n this.claimFailures = 0;\n } catch (error) {\n this.claimFailures++;\n console.error(\n `The queue could not claim jobs from its driver; it will try ` +\n `again in ${this.retryDelay()}ms.`,\n error,\n );\n } finally {\n this.claiming = undefined;\n }\n for (const job of claimed) this.execute(job);\n\n // A full batch may have left more behind; the next pass either claims\n // it or, with no room left, sleeps until a slot frees.\n if (claimed.length === room) continue;\n if (this.woken && this.inFlight.size < this.config.concurrency) {\n continue;\n }\n }\n\n await this.sleep();\n }\n }\n\n /**\n * Waits for the next thing worth waking for: a slot freeing, a `subscribe`\n * driver saying there is work, or the poll timer a driver without\n * `subscribe` gets.\n *\n * A claim that rejected arms a timer whatever the driver does, and that is\n * the whole reason this is not just the `subscribe` test. The wake that\n * prompted the lost claim has already been consumed, so a driver that only\n * speaks up on an enqueue — LISTEN/NOTIFY, say — has nothing left to\n * announce: an idle worker whose one claim died on a connection reset would\n * sit there, with every job already waiting, until some unrelated process\n * enqueued again. On a busy worker an in-flight job's `wake` covers it; an\n * idle one has nothing to be rescued by.\n *\n * The delay doubles per consecutive failure so that storage which is\n * properly down is not asked once a `pollInterval` for as long as it stays\n * down, and the first claim that returns clears the count.\n */\n private sleep() {\n return new Promise<void>((resolve) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const delay = this.claimFailures > 0\n ? this.retryDelay()\n : this.driver.subscribe\n ? undefined\n : this.config.pollInterval;\n if (delay !== undefined) {\n // Unref'd: a polling queue alone should not hold the process open.\n timer = setTimeout(() => this.wake(), delay);\n timer.unref?.();\n }\n this.resume = () => {\n clearTimeout(timer);\n resolve();\n };\n });\n }\n\n /** `pollInterval`, doubled once per consecutive claim failure, capped. */\n private retryDelay() {\n const doublings = Math.min(Math.max(0, this.claimFailures - 1), 30);\n return Math.min(this.config.pollInterval * 2 ** doublings, maxClaimBackoff);\n }\n\n private wake() {\n this.woken = true;\n const resume = this.resume;\n this.resume = undefined;\n resume?.();\n }\n\n /**\n * Whether the driver keeps jobs past this process: anything but memory.\n * Only such a queue can be fed by one process and drained by another.\n */\n get durable() {\n return !(this.driver instanceof MemoryQueueDriver);\n }\n\n /** See `claimsInThisProcess`. A manager built by hand always may. */\n private mayClaimHere() {\n return !this.application || claimsInThisProcess();\n }\n\n private lease(): ClaimOptions {\n return { visibilityTimeoutMs: this.config.visibilityTimeout };\n }\n\n private execute(claimed: ClaimedJob) {\n const key = `${claimed.id}:${claimed.attempt}`;\n const attempt = () => this.run(claimed);\n const done = (\n this.application\n ? kernelContext.run(this.application, attempt)\n : attempt()\n )\n .catch((error) => {\n // Only the driver's own reports reach here. The claim was not ended,\n // so its lease runs out and the job is claimed again.\n console.error(\n `The queue could not record the outcome of ${claimed.name}.`,\n error,\n );\n })\n .finally(() => {\n this.inFlight.delete(key);\n this.wake();\n });\n this.inFlight.set(key, { job: claimed, done });\n this.heartbeat();\n }\n\n /**\n * Keeps every running job's lease alive, at a third of the visibility\n * timeout so one late tick does not lose it. Stops itself once nothing is\n * running, and is unref'd, like the poll.\n */\n private heartbeat() {\n const driver = this.driver;\n if (!driver.heartbeat || this.heartbeatTimer) return;\n this.heartbeatTimer = setInterval(\n () => {\n if (this.inFlight.size === 0) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = undefined;\n return;\n }\n const jobs = [...this.inFlight.values()].map((e) => e.job);\n driver.heartbeat!(jobs, this.lease()).catch((error) => {\n console.error(`The queue could not extend its job leases.`, error);\n });\n },\n Math.max(1, Math.floor(this.config.visibilityTimeout / 3)),\n );\n this.heartbeatTimer.unref?.();\n }\n\n /**\n * One attempt at one claimed job, ending the claim either way.\n *\n * `onSuccess` is inside the `try`, as it always was, so a throw from it is a\n * failed attempt and is retried. `onFail` and `onDeadletter` are not: a\n * throw from either is logged and the claim still ends, where it used to\n * escape the queue with the job's slot still counted as taken.\n */\n private async run(claimed: ClaimedJob) {\n const Job = this.jobs[claimed.name];\n\n if (!Job) {\n // A driver other processes share may have handed this out because it\n // cannot filter by name, and while a blue/green ramp has both releases\n // claiming from one table, a name this replica lacks is usually one only\n // the other release has. So it goes back, without spending an attempt,\n // for a replica that has the class — until `unknownJobGrace` has passed\n // since the dispatch, after which the name is taken to be gone. Measured\n // from `createdAt` because that is all a claim carries; it is the\n // driver's clock against this one, and the skew is seconds against a\n // window of minutes. A driver that does filter only hands out an unknown\n // name once it has waited out the same window, so it normally lands\n // below; with this clock a few seconds behind the driver's, one handed\n // out right at the boundary is released instead, and — its window now\n // restarting from the release — waits one more `unknownJobGrace`. Late,\n // not lost, so no slack is subtracted for it.\n const age = Date.now() - claimed.createdAt;\n if (this.durable && age < this.config.unknownJobGrace) {\n // Once per name: with a driver that cannot filter, every poll can\n // claim the same job again, and a line per poll would bury the one\n // that matters — a replica whose discovery missed a job, say.\n if (!this.releasedNames.has(claimed.name)) {\n this.releasedNames.add(claimed.name);\n console.error(\n `Left a queued \"${claimed.name}\" for another replica: nothing is ` +\n `registered here under that name. It is dead-lettered if no ` +\n `replica has run it within unknownJobGrace ` +\n `(${this.config.unknownJobGrace}ms) of its dispatch.`,\n );\n }\n // Off this replica's own rhythm, and differently each time. It claims\n // again the moment the release lands, finds nothing due, and then\n // polls every `pollInterval`; a delay of exactly one interval made the\n // job due at the instant of that next poll, so the replica that could\n // not run it won the race for it every time. Any fixed fraction has\n // the same flaw for a replica whose polls happen to fall just before\n // the due moment each cycle — it loses every race, for good. Random\n // within one interval, every other replica's next poll has a chance.\n await this.driver.release(claimed, {\n retryInMs: Math.round(\n this.config.pollInterval * (1 + Math.random()),\n ),\n });\n return;\n }\n\n // The one place this is observable. A dispatch carries a name, the\n // registry is keyed by name, and a name nobody registered matches\n // nothing — which is exactly the silence #322 is about, except here it\n // has already happened and the work is gone. Saying so is all that is\n // left to do about it. Dead-lettered, which for the memory driver is the\n // drop it always was and for a durable one leaves a record to find.\n console.error(\n `Dropped a queued job: nothing is registered under the name ` +\n `\"${claimed.name}\". If the class exists, it was not ` +\n `discovered — check that it is under the queue slice's jobsDir ` +\n `(app/jobs by default), or list it in app/config/queue.ts.`,\n );\n await this.driver.fail(claimed, {\n error: `No job is registered under the name \"${claimed.name}\".`,\n retryInMs: null,\n });\n return;\n }\n\n let job: InstanceType<typeof Job>;\n try {\n job = new Job();\n } catch (error) {\n // A constructor or a class field that throws — `private mailer =\n // app(Mailer)` with nothing bound, say. Every other failure in here is\n // reported against the instance, and this one has no instance to report\n // against, which is exactly why it has to be caught here rather than\n // left to the generic path: that path never ends the claim, so the lease\n // lapses, the job is claimed again, and the constructor throws again,\n // once per visibility timeout, forever. The `maxAttempts` guard below\n // would normally stop that, and it cannot — answering \"how many attempts\n // does this job get?\" needs the instance that cannot be built. So it is\n // dead-lettered unrun, like a job whose arguments are not JSON: no\n // attempt of it can ever do anything but this.\n console.error(\n `Dropped a queued ${claimed.name}: it could not be constructed.`,\n error,\n );\n await this.driver.fail(claimed, {\n error: `The job could not be constructed: ${String(error)}`,\n retryInMs: null,\n });\n return;\n }\n\n let args: any[];\n try {\n args = JSON.parse(claimed.args);\n } catch (error) {\n // Not something `Job.dispatch` writes, so a driver changed it. Left\n // alone, the claim would never end and the job would be reclaimed,\n // unparseable, forever.\n console.error(\n `Dropped a queued ${claimed.name}: its arguments are not JSON.`,\n error,\n );\n await this.driver.fail(claimed, {\n error: `The arguments are not JSON: ${String(error)}`,\n retryInMs: null,\n });\n return;\n }\n\n // Claimed past its last attempt: an earlier claim used that attempt up and\n // never reported, which is what a process exiting mid-run looks like from\n // here. Running it again would exceed `maxAttempts`, so it is dead-lettered\n // unrun. `Math.max` keeps a `maxAttempts` below one meaning what it always\n // did — one attempt.\n if (claimed.attempt > Math.max(1, job.maxAttempts)) {\n const error = new Error(\n `${claimed.name} was claimed for attempt ${claimed.attempt} of ` +\n `${job.maxAttempts}: an earlier attempt never finished, most likely ` +\n `because the process running it exited. Dead-lettered without ` +\n `running it again.`,\n );\n hook(`${claimed.name}.onDeadletter`, () =>\n job.onDeadletter(error, ...args),\n );\n await this.driver.fail(claimed, {\n error: error.message,\n retryInMs: null,\n });\n return;\n }\n\n try {\n const result = await (job.worker\n ? runInWorker(claimed.name, claimed.args)\n : job.run(...args));\n\n job.onSuccess(result, ...args);\n } catch (err) {\n const error = err as Error;\n const recorded = String(error?.stack ?? error);\n hook(`${claimed.name}.onFail`, () => job.onFail(error, ...args));\n\n if (claimed.attempt >= job.maxAttempts) {\n hook(`${claimed.name}.onDeadletter`, () =>\n job.onDeadletter(error, ...args),\n );\n await this.driver.fail(claimed, { error: recorded, retryInMs: null });\n } else {\n await this.driver.fail(claimed, {\n error: recorded,\n retryInMs: backoffFor(job.backoff, claimed.attempt),\n });\n }\n return;\n }\n\n await this.driver.complete(claimed);\n }\n}\n\nfunction hook(name: string, fn: () => void) {\n try {\n fn();\n } catch (error) {\n console.error(`${name} threw; the job's claim was ended anyway.`, error);\n }\n}\n\nfunction isProduction() {\n return process.env.NODE_ENV === \"production\";\n}\n\n/**\n * Whether this process should claim from a driver shared with other\n * processes: a `gemi queue:work` worker, or a server's main thread unless\n * `GEMI_QUEUE_CLAIM=off` hands its jobs to workers. `ROOT_DIR` is set only by\n * a starting server or worker, so a console command, a seed\n * or a migration — which boot the same providers — is not one, and neither is\n * a `worker` job's thread, which clones the application and exits after it.\n *\n * A worker claims whatever `GEMI_QUEUE_CLAIM` says, because the variable is\n * for the web process, and a deploy that sets it once for every container\n * would otherwise leave nothing claiming at all.\n */\nexport function claimsInThisProcess() {\n if (!isMainThread) return false;\n if (isQueueWorker()) return true;\n return process.env.ROOT_DIR !== undefined && !claimingTurnedOff();\n}\n\n/**\n * `GEMI_QUEUE_CLAIM=off` (any case): this server dispatches into a shared\n * driver and leaves the claiming to `gemi queue:work` processes. Anything else\n * claims, as before. An environment variable rather than a config field for\n * the reason `GEMI_NO_SCHEDULE` is one: the web and the worker run the same\n * build with the same config, and only the process knows which it is.\n */\nexport function claimingTurnedOff(env: Record<string, string | undefined> = process.env) {\n return (env.GEMI_QUEUE_CLAIM ?? \"\").trim().toLowerCase() === \"off\";\n}\n\n// On `globalThis` under a registry symbol, like the shutdown flag, so the mark\n// the worker entry sets is the one this module reads if two copies of it are\n// loaded. Not an environment variable: a job that spawns a child process\n// would hand it on, and the child, a script, would start claiming.\nconst QUEUE_WORKER = Symbol.for(\"gemi.queue.worker\");\n\n/** Marks this process as a `gemi queue:work` worker; see `claimsInThisProcess`. */\nexport function markQueueWorker(worker = true) {\n (globalThis as { [QUEUE_WORKER]?: boolean })[QUEUE_WORKER] = worker;\n}\n\nexport function isQueueWorker(): boolean {\n return (globalThis as { [QUEUE_WORKER]?: boolean })[QUEUE_WORKER] === true;\n}\n\n/**\n * The delay before the retry that follows attempt `attempt`: the number\n * itself, or the array's entry for that retry with its last entry repeated.\n */\nexport function backoffFor(backoff: number | number[], attempt: number) {\n const delay = Array.isArray(backoff)\n ? backoff[Math.min(attempt, backoff.length) - 1]\n : backoff;\n return Math.max(0, delay ?? 0);\n}\n\nfunction resolveDriver(\n driver: Required<QueueConfig>[\"driver\"],\n application: Application | undefined,\n): QueueDriver {\n if (driver === \"memory\") return new MemoryQueueDriver();\n if (driver === \"database\" || typeof driver === \"function\") {\n // Only a manager built by hand has no application. A factory that takes\n // one would otherwise fail on `undefined` with a TypeError that names\n // neither the queue nor what is missing.\n if (!application && (driver === \"database\" || driver.length > 0)) {\n throw new Error(\n `The queue driver needs the application it belongs to, and this ` +\n `QueueManager was built without one. Pass { application }.`,\n );\n }\n if (driver === \"database\") {\n return new DatabaseQueueDriver(application!.make(DatabaseManager));\n }\n return driver(application!);\n }\n if (typeof driver === \"string\") {\n throw new Error(\n `Unknown queue driver \"${driver}\". The queue slice's driver is ` +\n `\"memory\", \"database\", a QueueDriver, or a function returning one.`,\n );\n }\n return driver;\n}\n"
9
9
  ],
10
10
  "mappings": "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",
11
- "debugId": "F0D1B1CBA0387DB764756E2164756E21",
11
+ "debugId": "6B52A7598A2A8F5E64756E2164756E21",
12
12
  "names": []
13
13
  }
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ import{pf as D}from"./chunk-rmv1jp9p.js";import{lg as i}from"./chunk-v27a4se1.js";import{yg as M}from"./chunk-r5e4vpa1.js";import{Fg as WH}from"./chunk-zfch4da5.js";class k{static kind="controller";constructor(){}}class l extends k{}function A(H){let R=new Map;if(!H)return R;for(let K of H.split(";")){let T=K.indexOf("=");if(T===-1)continue;let J=K.slice(0,T).trim();if(!J)continue;R.set(J,K.slice(T+1).trim())}return R}function PH(H){return A(H.headers.get("cookie"))}function P(H){if(!/^\d+$/.test(H))return null;let R=Number(H);return Number.isSafeInteger(R)?R:null}function c(H){if(!H)return null;let R=H.trim();if(!/^bytes=/i.test(R))return null;let T=R.slice(6).split(",").map((Y)=>Y.trim()).filter((Y)=>Y!=="");if(T.length!==1)return null;let J=T[0],G=J.indexOf("-");if(G===-1)return null;let O=J.slice(0,G),W=J.slice(G+1);if(O===""){let Y=P(W);if(Y===null)return null;return{kind:"suffix",suffixLength:Y}}let Q=P(O);if(Q===null)return null;if(W==="")return{kind:"offset",start:Q,end:null};let X=P(W);if(X===null||X<Q)return null;return{kind:"offset",start:Q,end:X}}function b(H,R){if(!Number.isFinite(R)||R<=0)return null;let K,T;if(H.kind==="suffix"){if(H.suffixLength<=0)return null;K=Math.max(0,R-H.suffixLength),T=R-1}else{if(H.start>=R)return null;if(K=H.start,T=H.end===null?R-1:Math.min(H.end,R-1),T<K)return null}return{start:K,end:T,length:T-K+1}}function LH(H){if(H.kind==="suffix")return`bytes=-${H.suffixLength}`;return H.end===null?`bytes=${H.start}-`:`bytes=${H.start}-${H.end}`}function jH(H){if(!H)return null;let R=/^bytes\s+(\d+)-(\d+)\/(\d+)$/i.exec(H.trim());if(!R)return null;let K=P(R[1]),T=P(R[2]),J=P(R[3]);if(K===null||T===null||J===null||T<K)return null;return{start:K,end:T,total:J}}function MH(H,R,K){return`bytes ${H}-${R}/${K}`}function f(H){return`bytes */${H}`}var xH="GEMI_REQUEST_BREAKER_ERROR";class Z extends Error{kind="GEMI_REQUEST_BREAKER_ERROR";payload={api:{},view:{}}}class B extends Z{errors={};constructor(H){super("Validation error");this.name="ValidationError",this.errors=H,this.payload={api:{status:400,data:{error:{kind:"validation_error",messages:H}},headers:{"Content-Type":"application/json"}},view:{status:400}}}}function r(H){let[R,K]=H.match(/\d+|\D+/g)??[];if(!R||!K)return 0;let T=Number.parseInt(R);switch(K){case"B":return T;case"KB":return T*1024;case"MB":return T*1024*1024;case"GB":return T*1024*1024*1024;case"TB":return T*1024*1024*1024*1024;default:return 0}}function a(H){switch(H){case"image":return"image";case"png":return"image/png";case"jpg":return"image/jpeg";case"jpeg":return"image/jpeg";case"ttf":return"font/ttf";case"excel":return"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";case"csv":return"text/csv";case"word":return"application/vnd.openxmlformats-officedocument.wordprocessingml.document";case"pdf":return"application/pdf";case"json":return"application/json";default:return H}}function g(H){if(typeof H==="string"||Array.isArray(H))return H.length;return}function F(H){return typeof H==="number"&&!Number.isNaN(H)}var e=["required","string","boolean","number","email","password","min","max","gte","lte","file","fileType","fileSize"];class $ extends Error{name="InvalidValidationRuleError"}function x(H,R){let K=R===void 0||R.trim()===""?Number.NaN:Number(R);if(Number.isNaN(K))throw new $(`Validation rule "${H}:${R??""}" needs a number, e.g. "${H}:3"`);return K}function v(H){let[R,K]=H.split(":");switch(R){case"required":return(T)=>{if(T instanceof Blob)return T.size>0;if(T===null||T===void 0)return!1;if(typeof T==="string"||Array.isArray(T))return T.length>0;return!0};case"string":return(T)=>typeof T==="string";case"boolean":return(T)=>typeof T==="boolean";case"number":return(T)=>F(T);case"password":return(T)=>{return typeof T==="string"&&/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/.test(T)};case"min":{let T=x(R,K);return(J)=>{let G=g(J);return G!==void 0&&G>=T}}case"max":{let T=x(R,K);return(J)=>{let G=g(J);return G!==void 0&&G<=T}}case"gte":{let T=x(R,K);return(J)=>F(J)&&J>=T}case"lte":{let T=x(R,K);return(J)=>F(J)&&J<=T}case"email":return(T)=>{return typeof T==="string"&&/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(T)};case"file":return(T)=>{return T instanceof Blob};case"fileType":{if(!K)throw new $('Validation rule "fileType" needs a type, e.g. "fileType:png" or "fileType:image"');let T=a(K);return(J)=>J instanceof Blob&&J.type.startsWith(T)}case"fileSize":{let T=r(K??"");if(T===0&&!/^0+(B|KB|MB|GB|TB)$/.test(K??""))throw new $(`Validation rule "fileSize:${K??""}" needs a whole size in B, KB, MB, GB or TB, e.g. "fileSize:5MB"`);return(J)=>J instanceof Blob&&J.size<=T}default:throw new $(`Unknown validation rule "${H}". Known rules: ${e.join(", ")}`)}}var N=new WeakMap;function VH(H,R){N.set(H,{clientAddress:R})}function h(H){return N.has(H)}function SH(H){return N.get(H)?.clientAddress}var d=new WeakMap;function _H(H,R){d.set(H,R)}function m(H){return d.get(H)??null}var V=new WeakMap;function EH(H,R){let K=V.get(H)??[];if(!K.includes(R))V.set(H,[...K,R])}function IH(H){return V.get(H)??[]}class C{data;constructor(H){this.data=H}get(H){return this.data[H]}has(H){return this.data[H]!==void 0}toJSON(){return this.data}}class HH{kind;rawRequest;headers;cookies;search;schema={};routePath;params;domain;constructor(H,R,K,T){if(!H){let Q=D.getStore().req;this.params=Q.params,this.rawRequest=Q.rawRequest,this.kind=Q.kind,this.routePath=Q.routePath,this.domain=Q.domain??null}else this.params=R,this.rawRequest=H,this.routePath=T,this.kind=K??"api",this.domain=m(H);this.headers=this.rawRequest.headers;let J=A(this.rawRequest.headers.get("Cookie")),G=new URL(this.rawRequest.url),O=new Map;for(let[Q,X]of G.searchParams)if(O.has(Q)){let Y=O.get(Q);if(Array.isArray(Y))Y.push(X),O.set(Q,Y);else O.set(Q,[Y,X])}else O.set(Q,X);let W=Object.fromEntries(O.entries());this.search=new C(W),this.cookies=J}locale(){return D.getStore().locale}ctx(){return D.getStore()}isModelOriginated(){return h(this.rawRequest)}range(){return c(this.rawRequest.headers.get("Range"))}refine(H){return{}}async parseBody(){let H=new C({});if(this.rawRequest.headers.get("Content-Type")==="application/json"){let R=await this.rawRequest.json();H=new C(R)}if(this.rawRequest.headers.get("Content-Type")==="application/x-www-form-urlencoded"){let R=await this.rawRequest.formData();H=new C(R)}if(this.rawRequest.headers.get("Content-Type")?.startsWith("multipart/form-data")){let R=await this.rawRequest.formData(),K=new Map;for(let[T,J]of R.entries())if(K.has(T)){let G=K.get(T);if(Array.isArray(G))G.push(J),K.set(T,G);else K.set(T,[G,J])}else K.set(T,J);H=new C(Object.fromEntries(K.entries()))}return H}validateInput(H){let R={},K=Object.entries(this.schema).map(([T,J])=>({key:T,rules:Object.entries(J).map(([G,O])=>({rule:G,message:O,check:typeof O==="function"?null:this.ruleFor(T,G)}))}));for(let{key:T,rules:J}of K){let G=H.get(T),O=J.some(({rule:X})=>X==="required"),W=G===void 0||G===null||G==="",Q=[];for(let{rule:X,message:Y,check:t}of J){let L=Y,z=!1;if(typeof Y==="function")L=Y(G),z=typeof L>"u";else z=t(G);if(z)continue;if(W&&!O)continue;if(X==="required"){Q.splice(0,Q.length,String(L));break}if(!Q.includes(String(L)))Q.push(String(L))}if(Q.length>0)R[T]=Q}for(let[T,J]of Object.entries(this.refine(H.toJSON())??{})){let G=R[T]??[];R[T]=G.includes(J)?G:[...G,J]}if(Object.keys(R).length>0)throw new B(R);return H}ruleFor(H,R){try{return v(R)}catch(K){if(K instanceof $)throw new $(`${this.constructor.name}.schema.${H}: ${K.message}`);throw K}}async input(){return this.validateInput(await this.parseBody())}async safeInput(){let H=await this.parseBody();try{return this.validateInput(H),{isValid:!0,errors:{},input:H}}catch(R){if(!(R instanceof B))throw R;return{isValid:!1,errors:R.errors,input:H}}}}class RH extends Z{error;constructor(H="Not authorized"){super(H);this.name="AuthorizationError",this.error=H,this.payload={api:{status:401,data:{error:this.error}},view:{}}}}class p extends Z{static apiStatus=403;error;constructor(H="Insufficient permissions"){super(H);this.name="InsufficientPermissionsError",this.error=H,this.payload={api:{status:p.apiStatus,data:{error:this.error}},view:{status:403}}}}class S extends Z{total;constructor(H){super("Range not satisfiable");this.total=H;this.name="RangeNotSatisfiableError",this.payload={api:{status:416,data:{error:{message:"Range not satisfiable"}},headers:{"Content-Range":f(H),"Accept-Ranges":"bytes","Cache-Control":"no-store"}},view:{}}}}class U extends Z{fileName;constructor(H){super("File not found");this.fileName=H;this.name="FileNotFoundError",this.payload={api:{status:404,data:{error:{message:"Not found"}},headers:{"Cache-Control":"no-store"}},view:{}}}}class TH extends Z{constructor(H={}){super("Authentication error");this.name="AuthenticationError";let R=H.redirectTo??"/auth/sign-in";this.payload={api:{status:401,data:{error:"Authentication error"}},viewData:{status:200,data:{},headers:{"Cache-Control":"private, no-cache, no-store, max-age=0, must-revalidate"},directive:{kind:"Redirect",path:R}},view:{status:302,headers:{"Cache-Control":"private, no-cache, no-store, max-age=0, must-revalidate",Location:R}}}}}class j{static getFacadeAccessor(){throw Error(`Facade [${this.name}] does not implement getFacadeAccessor().`)}static getFacadeRoot(){return i(this.getFacadeAccessor())}}class w{async delete(H){throw Error(`${this.constructor.name} does not implement delete(). Override it to remove objects from this backend.`)}async read(H){let R=typeof H==="string"?{name:H}:H,K=await this.fetch({name:R.name,bucket:R.bucket});if(!K.ok)throw new U(R.name);let T=K.headers.get("Content-Type")??"application/octet-stream",J=K.headers.get("ETag")??void 0,G=K.headers.get("Last-Modified"),O=G?new Date(G):void 0;if(R.range){let X=await K.blob();return{body:X,start:0,end:X.size-1,total:X.size,partial:!1,type:T,etag:J,lastModified:O,name:R.name}}let W=Number(K.headers.get("Content-Length")),Q=Number.isFinite(W)?W:0;return{body:K.body,start:0,end:Q-1,total:Q,partial:!1,type:T,etag:J,lastModified:O,name:R.name}}async size(H){let R=typeof H==="string"?H:H.name,K=typeof H==="string"?void 0:H.bucket,T=await this.fetch({name:R,bucket:K});if(!T.ok)throw new U(R);let J=Number(T.headers.get("Content-Length"));if(Number.isFinite(J))return await T.body?.cancel(),J;return(await T.blob()).size}}function u(H,R){if(!R)return H;let K=H.getReader(),T=!1,J,G=()=>{if(T=!0,J)R.removeEventListener("abort",J)};return new ReadableStream({start(O){if(J=()=>{if(T)return;G(),O.error(R.reason),K.cancel(R.reason).catch(()=>{})},R.aborted)J();else R.addEventListener("abort",J,{once:!0})},async pull(O){let W;try{W=await K.read()}catch(Q){if(T)return;G(),O.error(Q);return}if(T)return;if(W.done){G(),O.close();return}O.enqueue(W.value)},cancel(O){return G(),K.cancel(O)}},{highWaterMark:0})}import{readdir as KH,unlink as JH}from"fs/promises";import{isAbsolute as GH,relative as OH,resolve as n,sep as QH}from"path";class _ extends w{configured;constructor(H){super();this.configured=H}get folderPath(){return this.configured??`${M()}/storage`}async put(H,{signal:R}={}){R?.throwIfAborted();let K,T;if(H instanceof Blob)K=H,T=`${Bun.randomUUIDv7()}.${H.type.split("/")[1].split(";")[0]}`;else K=H.body,T=H.name;let J=K instanceof Buffer?K:K instanceof Blob||K instanceof File?Buffer.from(await K.arrayBuffer()):"",G=`${this.folderPath}/${T}`;return R?.throwIfAborted(),await Bun.write(G,J),T}async fetch(H,{signal:R}={}){R?.throwIfAborted();let K=process.env.BUCKET_NAME,T;if(typeof H==="string")T=H;else K=H.bucket??K,T=H.name;if(!T)throw Error("Object name has to be specified");let J=`${this.folderPath}/${T}`,G=Bun.file(J),O=u(Bun.file(J).stream(),R),W=new Date(G.lastModified).toUTCString();return new Response(O,{headers:{"Content-Type":G.type,"Content-Length":String(G.size),"Cache-Control":"private, max-age=12000, must-revalidate","Last-Modified":W}})}async read(H){let R=typeof H==="string"?{name:H}:H,{name:K,range:T=null}=R;if(!K)throw Error("Object name has to be specified");let J=Bun.file(`${this.folderPath}/${K}`);if(!await J.exists())throw new U(K);let G=J.size,O=T?b(T,G):null;if(T&&!O)throw new S(G);let W=O?.start??0,Q=O?O.end:G-1;return{body:O?J.slice(W,Q+1):J,start:W,end:Q,total:G,partial:Boolean(O),type:J.type||"application/octet-stream",lastModified:new Date(J.lastModified),name:K}}async size(H){let R=typeof H==="string"?H:H.name,K=Bun.file(`${this.folderPath}/${R}`);if(!await K.exists())throw new U(R);return K.size}async delete(H){let R=typeof H==="string"?H:H.name;if(!R)throw Error("Object name has to be specified");let K=n(this.folderPath),T=n(K,R),J=OH(K,T);if(!J||J===".."||J.startsWith(`..${QH}`)||GH(J))throw Error(`Refusing to delete "${R}": it is outside the storage folder`);try{await JH(T)}catch(G){if(G?.code==="ENOENT")return;throw G}}async list(){return await KH(this.folderPath)}}function JR(H){return H}function o(){return{driver:new _}}class E{static token="filesystem";driver;constructor(H={}){this.driver=H.driver??o().driver}}import{Buffer as XH}from"buffer";async function s(H){try{return(await import("sharp")).default}catch(R){throw Error(`${H} requires the 'sharp' package. Install it with \`bun add sharp\`.`,{cause:R})}}class YH extends j{static getFacadeAccessor(){return E}static async put(H,R={}){return this.getFacadeRoot().driver.put(H,R)}static async metadata(H){let R=XH.from(await H.arrayBuffer()),K=await s("Storage.metadata()");try{return await K(R).metadata()}catch{return{}}}static async fetch(H,R={}){return R.signal?.throwIfAborted(),this.getFacadeRoot().driver.fetch(H,R)}static async read(H,R={}){let K=typeof H==="string"?{name:H}:{...H},T="range"in R?R.range??null:K.range!==void 0?K.range:D.getStore()?.rangeRequest??null;return this.getFacadeRoot().driver.read({...K,range:T})}static list(H){return this.getFacadeRoot().driver.list(H)}static async delete(H){return this.getFacadeRoot().driver.delete(H)}}import{mkdir as I,readdir as ZH,access as $H}from"fs/promises";async function y(H){try{return await $H(H),!0}catch{return!1}}class q{config;static token="log";writer;isReady=!1;flushTimeout;fileSize=0;writerSize=0;isCreatingFile=!1;bootPromise=null;currentLogFilePath;get logsDirPath(){return`${M()}/storage/logs`}constructor(H){this.config=H}boot(){if(!this.bootPromise)this.bootPromise=this.createStorage().catch((H)=>{console.error("Log storage unavailable, file logging disabled",H)}).then(()=>{this.isReady=!0});return this.bootPromise}async createStorage(){let H=`${M()}/storage`;if(!await y(H))await I(H);if(!await y(this.logsDirPath))await I(this.logsDirPath);await this.newLogFile()}async newLogFile(){if(!await y(this.logsDirPath))await I(this.logsDirPath);if(this.isCreatingFile=!0,this.currentLogFilePath){this.writer.flush(),this.writer.end(),this.writer=null;let K=new File([await Bun.file(this.currentLogFilePath).arrayBuffer()],this.currentLogFilePath.split("/").pop(),{type:"text/plain"});this.config.onLogFileClosed(K),this.fileSize=0,this.writerSize=0}let R=(await ZH(this.logsDirPath)).sort().reverse()[0];if(R){let K=Bun.file(`${this.logsDirPath}/${R}`);if(K.size<this.config.maxFileSize)this.currentLogFilePath=`${this.logsDirPath}/${R}`,this.writer=K.writer(),this.writer.write(await K.text()),this.writer.write(`
3
+ `),this.writer.flush(),this.fileSize=K.size}if(!this.writer){let K=`${new Date(Date.now()).toISOString()}.log`.replaceAll(":","-");this.currentLogFilePath=`${this.logsDirPath}/${K}`;let T=Bun.file(`${this.logsDirPath}/${K}`);this.writer=T.writer(),this.fileSize=0,this.writerSize=0}this.isCreatingFile=!1}async log(H,R,K={}){if(!this.isReady)await this.boot();let T=D.getStore(),J={};if(T)J={url:T.req.rawRequest.url,method:T.req.rawRequest.method,headers:T.req.rawRequest.headers,body:T.req.rawRequest.body};let G={timestamp:new Date(Date.now()).toISOString(),env:Bun.env.NODE_ENV,level:H,message:R,metadata:{...J,...K}},O="";try{O=JSON.stringify(G)}catch(W){console.log("Error parsing log object",W)}try{let W=this.config.onLogCreated(G);if(W instanceof Promise)W.catch((Q)=>console.error("Error in onLogCreated",Q))}catch(W){console.error("Error in onLogCreated",W)}if(!this.writer)return;this.writerSize+=O.length,this.fileSize+=O.length;try{this.writer.write(O),this.writer.write(`
4
+ `),this.tryFlush()}catch(W){console.error("Error writing log",W)}}async tryFlush(){if(this.fileSize>this.config.maxFileSize){if(!this.isCreatingFile)await this.newLogFile()}if(this.writerSize>this.config.maxFileSize/2)await this.writer.flush(),this.writerSize=0,await this.newLogFile();else clearTimeout(this.flushTimeout),this.flushTimeout=setTimeout(async()=>{await this.writer.flush(),this.writerSize=0},100)}}class DH extends j{static getFacadeAccessor(){return q}static debug(H,R){this.getFacadeRoot().log("debug",H,R)}static info(H,R){this.getFacadeRoot().log("info",H,R)}static notice(H,R){this.getFacadeRoot().log("notice",H,R)}static warning(H,R){this.getFacadeRoot().log("warning",H,R)}static error(H,R){this.getFacadeRoot().log("error",H,R)}static critical(H,R){this.getFacadeRoot().log("critical",H,R)}static alert(H,R){this.getFacadeRoot().log("alert",H,R)}static emergency(H,R){this.getFacadeRoot().log("emergency",H,R)}}
5
+ export{k as Fe,l as Ge,PH as He,VH as Ie,SH as Je,c as Ke,b as Le,LH as Me,jH as Ne,MH as Oe,f as Pe,_H as Qe,m as Re,EH as Se,IH as Te,xH as Ue,Z as Ve,B as We,$ as Xe,HH as Ye,RH as Ze,p as _e,S as $e,U as af,TH as bf,j as cf,s as df,w as ef,u as ff,_ as gf,JR as hf,o as if,E as jf,YH as kf,q as lf,DH as mf};
6
+
7
+ //# debugId=402F43E221AB2F3A64756E2164756E21
@@ -10,7 +10,7 @@
10
10
  "/**\n * The validation rule table: a rule name in, a predicate out.\n *\n * ITS OWN MODULE SO THE TEST DOES NOT NEED A HOOK. This lived in\n * `HttpRequest.ts` and was reached from `validate.test.ts` through\n * `export const __validateForTests = validate`, which is a name that exists\n * only because the thing it aliases was in the wrong file. Two costs, and the\n * second is the one that bites:\n *\n * - `tsc` emits a declaration per source file, so `dist/http/HttpRequest.d.ts`\n * shipped `__validateForTests` to every installed copy of the framework. The\n * JS build bundles, so there is no `dist/http/HttpRequest.js` behind it —\n * the declaration announced an export the tarball could not produce.\n * - A test-only alias is a second name for the same function, so the test\n * reads as if it were poking at something private. It is not: this is the\n * code path every request body goes through. Importing `validate` says so.\n *\n * Nothing outside `HttpRequest` should build predicates by hand — rules are\n * named in a route's schema — but \"internal\" is what an unexported name in an\n * unexported module already means, and it does not need a warning label.\n */\n\n// Formats B KB MB GB TB\n// e.g parseFileSizeString(\"1MB\") => 1024 * 1024\nfunction parseFileSizeString(size: string) {\n const [number, unit] = size.match(/\\d+|\\D+/g) ?? [];\n if (!number || !unit) {\n return 0;\n }\n const fileSize = Number.parseInt(number);\n switch (unit) {\n case \"B\":\n return fileSize;\n case \"KB\":\n return fileSize * 1024;\n case \"MB\":\n return fileSize * 1024 * 1024;\n case \"GB\":\n return fileSize * 1024 * 1024 * 1024;\n case \"TB\":\n return fileSize * 1024 * 1024 * 1024 * 1024;\n default:\n return 0;\n }\n}\n\n// Formats png, jpg, ttf, excel, csv, word, pdf, json\n// Eg. png => image/png\nfunction parseFileTypeString(type: string) {\n switch (type) {\n case \"image\":\n return \"image\";\n case \"png\":\n return \"image/png\";\n case \"jpg\":\n return \"image/jpeg\";\n case \"jpeg\":\n return \"image/jpeg\";\n case \"ttf\":\n return \"font/ttf\";\n case \"excel\":\n return \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n case \"csv\":\n return \"text/csv\";\n case \"word\":\n return \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\";\n case \"pdf\":\n return \"application/pdf\";\n case \"json\":\n return \"application/json\";\n default:\n return type;\n }\n}\n\n/** The length of the things that have one — `undefined` for everything else,\n * rather than the `undefined` that arithmetic silently turns into `false`. */\nfunction lengthOf(value: any): number | undefined {\n if (typeof value === \"string\" || Array.isArray(value)) return value.length;\n return undefined;\n}\n\nfunction isNumber(value: any): value is number {\n return typeof value === \"number\" && !Number.isNaN(value);\n}\n\n/** Every rule `validate` implements. `SchemaKey` in `HttpRequest.ts` offers\n * these and only these: `validate.test-d.ts` checks the two lists agree, and\n * `validate.test.ts` that each one has a case. */\nexport const RULES = [\n \"required\",\n \"string\",\n \"boolean\",\n \"number\",\n \"email\",\n \"password\",\n \"min\",\n \"max\",\n \"gte\",\n \"lte\",\n \"file\",\n \"fileType\",\n \"fileSize\",\n] as const;\n\n/**\n * A schema names a rule `validate` does not have, or gives one a parameter it\n * cannot use. Thrown when the request is validated, not when the body is bad:\n * it is a bug in the schema, so it is a 500 and not a 400.\n */\nexport class InvalidValidationRuleError extends Error {\n name = \"InvalidValidationRuleError\";\n}\n\n/** `min:3` → 3. A parameter that is not a number throws, instead of becoming\n * `NaN` and quietly failing every value. */\nfunction numericParam(rule: string, param: string | undefined): number {\n const n = param === undefined || param.trim() === \"\" ? Number.NaN : Number(param);\n if (Number.isNaN(n)) {\n throw new InvalidValidationRuleError(\n `Validation rule \"${rule}:${param ?? \"\"}\" needs a number, e.g. \"${rule}:3\"`,\n );\n }\n return n;\n}\n\nexport function validate(ruleName: string) {\n const [rule, param] = ruleName.split(\":\");\n switch (rule) {\n /**\n * Present. Not \"non-empty for the two types that happen to have `.length`\".\n *\n * This used to end in `value?.length > 0`, which is `undefined > 0` — so\n * `false` — for every value that is not a string, an array or a Blob. A\n * number failed it. A boolean failed it. A plain object failed it, which on\n * a typed `HttpRequest<{ theme: { … } }>` is the ordinary case, and the app\n * saw a 400 on a request that was correct.\n *\n * `0` and `false` PASS. They are values someone sent, and a rule called\n * `required` asks whether the field is there, not whether it is truthy —\n * conflating those is how a checkbox set to \"no\" and a quantity of zero get\n * rejected as missing. Emptiness is still emptiness where the concept\n * applies: `\"\"` and `[]` fail, as they did before, and so does a zero-byte\n * upload.\n *\n * `{}` passes. It is an object that was sent; whether its contents are\n * adequate is a question for the rules on its fields, not for this one.\n */\n case \"required\":\n return (value: any) => {\n if (value instanceof Blob) {\n return value.size > 0;\n }\n if (value === null || value === undefined) {\n return false;\n }\n if (typeof value === \"string\" || Array.isArray(value)) {\n return value.length > 0;\n }\n return true;\n };\n /**\n * The JSON types, checked with `typeof` like `number`. No coercion: `\"true\"`\n * is not a boolean and `42` is not a string. A form-encoded or multipart\n * body only ever carries strings (and files), so `boolean` and `number` are\n * rules for JSON bodies.\n */\n case \"string\":\n return (value: any) => typeof value === \"string\";\n case \"boolean\":\n return (value: any) => typeof value === \"boolean\";\n case \"number\":\n return (value: any) => isNumber(value);\n /**\n * `RegExp.prototype.test` stringifies its argument, so without the `typeof`\n * check `[\"a@b.co\"]` passed `email` and an array holding a strong password\n * passed `password`.\n */\n case \"password\":\n return (value: any) => {\n // min 8 characters\n // at least one uppercase letter,\n // at least one lowercase letter and one number\n // at least one special character\n const passwordRegex = /^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/;\n return typeof value === \"string\" && passwordRegex.test(value);\n };\n /**\n * Length, and only length. `min:3` is \"at least three characters\", never\n * \"at least three\".\n *\n * ONE NAME, ONE COMPARISON, deliberately. The tempting fix was to overload\n * these by runtime type — length for a string, magnitude for a number — and\n * that is the shape `required` was already in: a rule whose meaning depends\n * on what it is handed, which reads fine until the value's type is not the\n * one the author pictured. `gte` / `lte` below say which comparison they\n * make in their names, so nothing has to be inferred.\n *\n * Written out rather than left as `value?.length >= n` so that a number\n * fails here for a stated reason instead of by arithmetic on `undefined`.\n */\n case \"min\": {\n const min = numericParam(rule, param);\n return (value: any) => {\n const length = lengthOf(value);\n return length !== undefined && length >= min;\n };\n }\n case \"max\": {\n const max = numericParam(rule, param);\n return (value: any) => {\n const length = lengthOf(value);\n return length !== undefined && length <= max;\n };\n }\n /** Magnitude, for numbers. The counterpart `min` / `max` deliberately are not. */\n case \"gte\": {\n const bound = numericParam(rule, param);\n return (value: any) => isNumber(value) && value >= bound;\n }\n case \"lte\": {\n const bound = numericParam(rule, param);\n return (value: any) => isNumber(value) && value <= bound;\n }\n case \"email\":\n return (value: any) => {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return typeof value === \"string\" && emailRegex.test(value);\n };\n case \"file\":\n return (value: any) => {\n return value instanceof Blob;\n };\n case \"fileType\": {\n if (!param) {\n throw new InvalidValidationRuleError(\n `Validation rule \"fileType\" needs a type, e.g. \"fileType:png\" or \"fileType:image\"`,\n );\n }\n const parsedType = parseFileTypeString(param);\n return (value: any) => value instanceof Blob && value.type.startsWith(parsedType);\n }\n case \"fileSize\": {\n // `parseFileSizeString` answers 0 for anything it cannot read, and a\n // 0-byte ceiling rejects every upload — so `fileSize:5mb` or\n // `fileSize:1.5MB` looked like a limit and was a wall.\n const absoluteSize = parseFileSizeString(param ?? \"\");\n if (absoluteSize === 0 && !/^0+(B|KB|MB|GB|TB)$/.test(param ?? \"\")) {\n throw new InvalidValidationRuleError(\n `Validation rule \"fileSize:${param ?? \"\"}\" needs a whole size in B, KB, MB, GB or TB, e.g. \"fileSize:5MB\"`,\n );\n }\n return (value: any) => value instanceof Blob && value.size <= absoluteSize;\n }\n /**\n * Not `() => true`. That default is how `string` and `boolean` shipped in\n * `SchemaKey` checking nothing (#609): a rule the table does not\n * know looks, from the schema, exactly like one it does. A typo'd or\n * unimplemented rule is a bug in the schema, so it throws.\n */\n default:\n throw new InvalidValidationRuleError(\n `Unknown validation rule \"${ruleName}\". Known rules: ${RULES.join(\", \")}`,\n );\n }\n}\n",
11
11
  "/**\n * The requests the api dispatcher built itself, on a model's behalf, rather\n * than received from a client.\n *\n * Keyed on the `Request` object, not carried in it. A header was the obvious\n * alternative and it is forgeable by construction: anything the synthetic\n * request can carry, a real client can send. Only a module holding this set can\n * add to it, and it is deliberately not re-exported from `http/index.ts`, so no\n * inbound request can put itself here. The only writer is\n * `ApiRouteDispatcher.dispatchAs`, and it marks only the requests it built.\n * App code can call `dispatchAs` — it is trusted — but cannot mark a request of\n * its own.\n *\n * The object, rather than a flag on the request context, because the two\n * places an app asks the question sit on either side of `RequestContext.run`:\n * `onRequestStart` fires before the dispatcher opens the request's store, and a\n * handler's `new SomeRequest()` builds a second `HttpRequest` from inside it.\n * Both wrap the same raw `Request`, so both get the same answer, and nothing has\n * to remember to copy a field from one to the other.\n *\n * A `WeakMap`, so a dispatched request is forgotten with the request. The\n * value is the initiator's client address; see `dispatchedClientAddress`.\n */\nconst dispatched = new WeakMap<Request, { clientAddress: string }>();\n\n/**\n * `clientAddress` is required so the one writer cannot mark a request without\n * saying whose rate-limit budget it spends.\n */\nexport function markModelOriginated(req: Request, clientAddress: string) {\n dispatched.set(req, { clientAddress });\n}\n\nexport function isModelOriginated(req: Request): boolean {\n return dispatched.has(req);\n}\n\n/**\n * The client address `clientIp` resolved from the initiator, for a request the\n * dispatcher built; `undefined` for any other.\n *\n * It rides here for the same reason the marker does. The synthetic request\n * carries credentials only, so it has no `x-forwarded-for`, and\n * `RateLimitMiddleware` would key every tool call from every user on\n * `unknown:<route>`: one budget, which one user's agent loop can spend for\n * everyone. Copying the initiator's `x-forwarded-for` instead would move a\n * client-written header onto a request the server built. Carrying the value\n * `clientIp` already derived from the initiator gives a tool call exactly the\n * address the user's own direct request gets, and nothing more.\n */\nexport function dispatchedClientAddress(req: Request): string | undefined {\n return dispatched.get(req)?.clientAddress;\n}\n",
12
12
  "// Type-only: `services/router` imports from `http`, so a runtime import here\n// would be circular.\nimport type { ResolvedDomain } from \"../services/router/DomainResolver\";\n\n// Keyed by the raw Request, so the domain `App.fetch` resolved reaches the\n// dispatcher, and every `HttpRequest` built over that Request, without a\n// second AsyncLocalStorage that a streaming render would step outside of.\nconst domains = new WeakMap<Request, ResolvedDomain>();\n\nexport function setRequestDomain(req: Request, domain: ResolvedDomain) {\n domains.set(req, domain);\n}\n\n/** The host group `req` was routed by, or `null` when `route.domains` is not configured. */\nexport function requestDomain(req: Request): ResolvedDomain | null {\n return domains.get(req) ?? null;\n}\n\n// Headers meant for this app alone — `route.domains.trustProxy.secret` — that\n// a `proxy()` route must not forward upstream with the rest of the client's.\nconst withheld = new WeakMap<Request, string[]>();\n\nexport function withholdFromUpstream(req: Request, header: string) {\n const headers = withheld.get(req) ?? [];\n if (!headers.includes(header)) {\n withheld.set(req, [...headers, header]);\n }\n}\n\n/** The lowercased header names a `proxy()` route drops from `req` before forwarding it. */\nexport function withheldFromUpstream(req: Request): readonly string[] {\n return withheld.get(req) ?? [];\n}\n",
13
- "import { parseCookieHeader } from \"./getCookies\";\nimport { isModelOriginated } from \"./modelOriginated\";\nimport { parseRangeHeader } from \"./range\";\nimport { RequestContext } from \"./requestContext\";\nimport { requestDomain } from \"./requestDomain\";\nimport { ValidationError } from \"./Router\";\nimport { InvalidValidationRuleError, validate } from \"./validate\";\nimport type { ResolvedDomain } from \"../services/router/DomainResolver\";\n\nclass Input<T> {\n constructor(private data: T) {}\n\n public get<K extends keyof T>(key: K): T[K] {\n return this.data[key];\n }\n\n public has(key: keyof T) {\n return this.data[key] !== undefined;\n }\n\n public toJSON(): T {\n return this.data;\n }\n}\n\ntype StringType = \"string\";\ntype NumberType = \"number\";\ntype BooleanType = \"boolean\";\ntype MinLengthType = `min:${number}`;\ntype MaxLengthType = `max:${number}`;\n/** Magnitude, for numbers — see `validate`'s `min` case for why these are not\n * the same rule wearing different names. */\ntype GreaterOrEqualType = `gte:${number}`;\ntype LessOrEqualType = `lte:${number}`;\ntype RequiredType = \"required\";\ntype FileType = \"file\";\n// Backticks, not quotes. These two were written with double quotes, which makes\n// them the *literal text* `fileType:${string}` rather than a template literal\n// type — so `fileType:image/png`, the only way anyone would ever write the rule,\n// did not typecheck, while the runtime handled it perfectly well.\ntype FileTypeType = `fileType:${string}`;\ntype FileSizeType = `fileSize:${string}`;\ntype EmailType = \"email\";\ntype PasswordType = \"password\";\n/** One entry per rule in `validate`'s `RULES`; `validate.test-d.ts` holds them\n * to each other, so an offered rule cannot go unimplemented again (#609). */\nexport type SchemaKey =\n | StringType\n | NumberType\n | BooleanType\n | MinLengthType\n | MaxLengthType\n | GreaterOrEqualType\n | LessOrEqualType\n | RequiredType\n | FileType\n | FileTypeType\n | FileSizeType\n | EmailType\n | PasswordType;\n\nexport type Schema<T extends Body> = Record<keyof T, Partial<Record<SchemaKey, string>>>;\n\nexport type Body = Record<string, any>;\nexport type HttpRequestKind = \"view\" | \"api\";\n\nexport class HttpRequest<T extends Body = Record<string, never>, Params = Record<string, never>> {\n kind: HttpRequestKind;\n rawRequest: Request;\n headers: Omit<Headers, \"set\" | \"delete\">;\n cookies: Omit<Map<string, string>, \"set\" | \"delete\">;\n search: Input<any>;\n schema: any = {};\n routePath: string;\n params: Params;\n /**\n * The `route.domains` group this request was routed by — `domain.params`\n * holds a `:param` subdomain's value, or what `custom.resolve` returned for\n * a custom domain. `null` when the app declares no `route.domains`.\n *\n * Kept apart from `params`, which are the path's alone.\n */\n domain: ResolvedDomain | null;\n\n constructor(req?: Request, params?: any, kind?: HttpRequestKind, routePath?: string) {\n if (!req) {\n const _req = RequestContext.getStore().req;\n this.params = _req.params as any;\n this.rawRequest = _req.rawRequest;\n this.kind = _req.kind;\n this.routePath = _req.routePath;\n this.domain = _req.domain ?? null;\n } else {\n this.params = params;\n this.rawRequest = req;\n this.routePath = routePath;\n this.kind = kind ?? \"api\";\n this.domain = requestDomain(req);\n }\n\n this.headers = this.rawRequest.headers;\n\n const cookies = parseCookieHeader(this.rawRequest.headers.get(\"Cookie\"));\n const url = new URL(this.rawRequest.url);\n const map = new Map<string, string | string[]>();\n for (const [key, value] of url.searchParams) {\n if (map.has(key)) {\n const currentValue = map.get(key);\n if (Array.isArray(currentValue)) {\n currentValue.push(value);\n map.set(key, currentValue);\n } else {\n map.set(key, [currentValue, value]);\n }\n } else {\n map.set(key, value);\n }\n }\n const _params = Object.fromEntries(map.entries());\n this.search = new Input(_params);\n this.cookies = cookies;\n }\n\n locale() {\n return RequestContext.getStore().locale;\n }\n\n ctx() {\n return RequestContext.getStore();\n }\n\n /**\n * Whether the framework dispatched this request in-process for a model — a\n * tool call — rather than a client sending it. Readable in `onRequestStart`,\n * in middleware and in the handler alike.\n *\n * No header or cookie can make this true; see `http/modelOriginated.ts`.\n */\n isModelOriginated(): boolean {\n return isModelOriginated(this.rawRequest);\n }\n\n /**\n * The parsed `Range` header, or `null` when absent or unusable. Pass it to\n * `FileStorage.read(name, { range })` to range explicitly; inside a\n * `this.stream()` route `read()` already picks it up on its own.\n */\n range() {\n return parseRangeHeader(this.rawRequest.headers.get(\"Range\"));\n }\n\n refine(_input: any): any {\n return {};\n }\n\n private async parseBody() {\n let inputMap = new Input<T>({} as T);\n if (this.rawRequest.headers.get(\"Content-Type\") === \"application/json\") {\n const body = await this.rawRequest.json();\n inputMap = new Input<T>(body as T);\n }\n if (this.rawRequest.headers.get(\"Content-Type\") === \"application/x-www-form-urlencoded\") {\n const body = (await this.rawRequest.formData()) as any; // TODO: fix type\n inputMap = new Input<T>(body as T);\n }\n\n if (this.rawRequest.headers.get(\"Content-Type\")?.startsWith(\"multipart/form-data\")) {\n const body = (await this.rawRequest.formData()) as any; // TODO: fix type\n const _inputMap = new Map<string, any>();\n for (const [key, value] of body.entries()) {\n if (_inputMap.has(key)) {\n const currentValue = _inputMap.get(key);\n if (Array.isArray(currentValue)) {\n currentValue.push(value);\n _inputMap.set(key, currentValue);\n } else {\n _inputMap.set(key, [currentValue, value] as any);\n }\n } else {\n _inputMap.set(key, value as T[keyof T]);\n }\n }\n inputMap = new Input<T>(Object.fromEntries(_inputMap.entries()) as T);\n }\n return inputMap;\n }\n\n private validateInput(input: Input<T>) {\n const errors: Record<string, string[]> = {};\n const fields = Object.entries(this.schema as Record<string, Record<string, unknown>>).map(\n ([key, rules]) => ({\n key,\n // Every rule is looked up before any value is checked, so a schema that\n // names an unknown rule throws on every request, whatever the body —\n // not only on the ones whose earlier rules happened to pass. A function\n // is its own validator: its key is a label, and is not looked up.\n rules: Object.entries(rules).map(([rule, message]) => ({\n rule,\n message,\n check: typeof message === \"function\" ? null : this.ruleFor(key, rule),\n })),\n }),\n );\n\n for (const { key, rules } of fields) {\n const value = input.get(key as keyof T);\n const isRequired = rules.some(({ rule }) => rule === \"required\");\n // Absent: skipped unless `required`. `0` and `false` are values, and are\n // checked like any other — skipping every falsy value let `0` and `false` through a\n // `string` rule and `0` through a `boolean` one.\n const isAbsent = value === undefined || value === null || (value as unknown) === \"\";\n const messages: string[] = [];\n\n for (const { rule, message, check } of rules) {\n let _message = message;\n let _isValid = false;\n if (typeof message === \"function\") {\n _message = message(value);\n _isValid = typeof _message === \"undefined\";\n } else {\n _isValid = check!(value);\n }\n\n if (_isValid) {\n continue;\n }\n\n if (isAbsent && !isRequired) {\n continue;\n }\n\n if (rule === \"required\") {\n // A missing field reports that it is missing, and only that — not\n // also that `undefined` is not a string. Wherever `required` sits\n // among the field's rules.\n messages.splice(0, messages.length, String(_message));\n break;\n }\n\n messages.push(String(_message));\n }\n\n if (messages.length > 0) {\n errors[key] = messages;\n }\n }\n\n for (const [key, value] of Object.entries(this.refine(input.toJSON()) ?? {})) {\n if (!errors[key]) {\n errors[key] = [];\n }\n errors[key] = [...(errors[key] ?? []), value as string];\n }\n\n if (Object.keys(errors).length > 0) {\n throw new ValidationError(errors);\n }\n\n return input;\n }\n\n private ruleFor(key: string, rule: string) {\n try {\n return validate(rule);\n } catch (err) {\n if (err instanceof InvalidValidationRuleError) {\n throw new InvalidValidationRuleError(\n `${this.constructor.name}.schema.${key}: ${err.message}`,\n );\n }\n throw err;\n }\n }\n\n async input(): Promise<Input<T>> {\n return this.validateInput(await this.parseBody());\n }\n\n async safeInput(): Promise<{\n isValid: boolean;\n errors: Record<string, string[]>;\n input: Input<T>;\n }> {\n const input = await this.parseBody();\n try {\n this.validateInput(input);\n return {\n isValid: true,\n errors: {},\n input,\n };\n } catch (err) {\n if (!(err instanceof ValidationError)) {\n throw err;\n }\n return {\n isValid: false,\n errors: err.errors,\n input,\n };\n }\n }\n}\n",
13
+ "import { parseCookieHeader } from \"./getCookies\";\nimport { isModelOriginated } from \"./modelOriginated\";\nimport { parseRangeHeader } from \"./range\";\nimport { RequestContext } from \"./requestContext\";\nimport { requestDomain } from \"./requestDomain\";\nimport { ValidationError } from \"./Router\";\nimport { InvalidValidationRuleError, validate } from \"./validate\";\nimport type { ResolvedDomain } from \"../services/router/DomainResolver\";\n\nclass Input<T> {\n constructor(private data: T) {}\n\n public get<K extends keyof T>(key: K): T[K] {\n return this.data[key];\n }\n\n public has(key: keyof T) {\n return this.data[key] !== undefined;\n }\n\n public toJSON(): T {\n return this.data;\n }\n}\n\ntype StringType = \"string\";\ntype NumberType = \"number\";\ntype BooleanType = \"boolean\";\ntype MinLengthType = `min:${number}`;\ntype MaxLengthType = `max:${number}`;\n/** Magnitude, for numbers — see `validate`'s `min` case for why these are not\n * the same rule wearing different names. */\ntype GreaterOrEqualType = `gte:${number}`;\ntype LessOrEqualType = `lte:${number}`;\ntype RequiredType = \"required\";\ntype FileType = \"file\";\n// Backticks, not quotes. These two were written with double quotes, which makes\n// them the *literal text* `fileType:${string}` rather than a template literal\n// type — so `fileType:image/png`, the only way anyone would ever write the rule,\n// did not typecheck, while the runtime handled it perfectly well.\ntype FileTypeType = `fileType:${string}`;\ntype FileSizeType = `fileSize:${string}`;\ntype EmailType = \"email\";\ntype PasswordType = \"password\";\n/** One entry per rule in `validate`'s `RULES`; `validate.test-d.ts` holds them\n * to each other, so an offered rule cannot go unimplemented again (#609). */\nexport type SchemaKey =\n | StringType\n | NumberType\n | BooleanType\n | MinLengthType\n | MaxLengthType\n | GreaterOrEqualType\n | LessOrEqualType\n | RequiredType\n | FileType\n | FileTypeType\n | FileSizeType\n | EmailType\n | PasswordType;\n\nexport type Schema<T extends Body> = Record<keyof T, Partial<Record<SchemaKey, string>>>;\n\nexport type Body = Record<string, any>;\nexport type HttpRequestKind = \"view\" | \"api\";\n\nexport class HttpRequest<T extends Body = Record<string, never>, Params = Record<string, never>> {\n kind: HttpRequestKind;\n rawRequest: Request;\n headers: Omit<Headers, \"set\" | \"delete\">;\n cookies: Omit<Map<string, string>, \"set\" | \"delete\">;\n search: Input<any>;\n schema: any = {};\n routePath: string;\n params: Params;\n /**\n * The `route.domains` group this request was routed by — `domain.params`\n * holds a `:param` subdomain's value, or what `custom.resolve` returned for\n * a custom domain. `null` when the app declares no `route.domains`.\n *\n * Kept apart from `params`, which are the path's alone.\n */\n domain: ResolvedDomain | null;\n\n constructor(req?: Request, params?: any, kind?: HttpRequestKind, routePath?: string) {\n if (!req) {\n const _req = RequestContext.getStore().req;\n this.params = _req.params as any;\n this.rawRequest = _req.rawRequest;\n this.kind = _req.kind;\n this.routePath = _req.routePath;\n this.domain = _req.domain ?? null;\n } else {\n this.params = params;\n this.rawRequest = req;\n this.routePath = routePath;\n this.kind = kind ?? \"api\";\n this.domain = requestDomain(req);\n }\n\n this.headers = this.rawRequest.headers;\n\n const cookies = parseCookieHeader(this.rawRequest.headers.get(\"Cookie\"));\n const url = new URL(this.rawRequest.url);\n const map = new Map<string, string | string[]>();\n for (const [key, value] of url.searchParams) {\n if (map.has(key)) {\n const currentValue = map.get(key);\n if (Array.isArray(currentValue)) {\n currentValue.push(value);\n map.set(key, currentValue);\n } else {\n map.set(key, [currentValue, value]);\n }\n } else {\n map.set(key, value);\n }\n }\n const _params = Object.fromEntries(map.entries());\n this.search = new Input(_params);\n this.cookies = cookies;\n }\n\n locale() {\n return RequestContext.getStore().locale;\n }\n\n ctx() {\n return RequestContext.getStore();\n }\n\n /**\n * Whether the framework dispatched this request in-process for a model — a\n * tool call — rather than a client sending it. Readable in `onRequestStart`,\n * in middleware and in the handler alike.\n *\n * No header or cookie can make this true; see `http/modelOriginated.ts`.\n */\n isModelOriginated(): boolean {\n return isModelOriginated(this.rawRequest);\n }\n\n /**\n * The parsed `Range` header, or `null` when absent or unusable. Pass it to\n * `FileStorage.read(name, { range })` to range explicitly; inside a\n * `this.stream()` route `read()` already picks it up on its own.\n */\n range() {\n return parseRangeHeader(this.rawRequest.headers.get(\"Range\"));\n }\n\n refine(_input: any): any {\n return {};\n }\n\n private async parseBody() {\n let inputMap = new Input<T>({} as T);\n if (this.rawRequest.headers.get(\"Content-Type\") === \"application/json\") {\n const body = await this.rawRequest.json();\n inputMap = new Input<T>(body as T);\n }\n if (this.rawRequest.headers.get(\"Content-Type\") === \"application/x-www-form-urlencoded\") {\n const body = (await this.rawRequest.formData()) as any; // TODO: fix type\n inputMap = new Input<T>(body as T);\n }\n\n if (this.rawRequest.headers.get(\"Content-Type\")?.startsWith(\"multipart/form-data\")) {\n const body = (await this.rawRequest.formData()) as any; // TODO: fix type\n const _inputMap = new Map<string, any>();\n for (const [key, value] of body.entries()) {\n if (_inputMap.has(key)) {\n const currentValue = _inputMap.get(key);\n if (Array.isArray(currentValue)) {\n currentValue.push(value);\n _inputMap.set(key, currentValue);\n } else {\n _inputMap.set(key, [currentValue, value] as any);\n }\n } else {\n _inputMap.set(key, value as T[keyof T]);\n }\n }\n inputMap = new Input<T>(Object.fromEntries(_inputMap.entries()) as T);\n }\n return inputMap;\n }\n\n private validateInput(input: Input<T>) {\n const errors: Record<string, string[]> = {};\n const fields = Object.entries(this.schema as Record<string, Record<string, unknown>>).map(\n ([key, rules]) => ({\n key,\n // Every rule is looked up before any value is checked, so a schema that\n // names an unknown rule throws on every request, whatever the body —\n // not only on the ones whose earlier rules happened to pass. A function\n // is its own validator: its key is a label, and is not looked up.\n rules: Object.entries(rules).map(([rule, message]) => ({\n rule,\n message,\n check: typeof message === \"function\" ? null : this.ruleFor(key, rule),\n })),\n }),\n );\n\n for (const { key, rules } of fields) {\n const value = input.get(key as keyof T);\n const isRequired = rules.some(({ rule }) => rule === \"required\");\n // Absent: skipped unless `required`. `0` and `false` are values, and are\n // checked like any other — skipping every falsy value let `0` and `false` through a\n // `string` rule and `0` through a `boolean` one.\n const isAbsent = value === undefined || value === null || (value as unknown) === \"\";\n const messages: string[] = [];\n\n for (const { rule, message, check } of rules) {\n let _message = message;\n let _isValid = false;\n if (typeof message === \"function\") {\n _message = message(value);\n _isValid = typeof _message === \"undefined\";\n } else {\n _isValid = check!(value);\n }\n\n if (_isValid) {\n continue;\n }\n\n if (isAbsent && !isRequired) {\n continue;\n }\n\n if (rule === \"required\") {\n // A missing field reports that it is missing, and only that — not\n // also that `undefined` is not a string. Wherever `required` sits\n // among the field's rules.\n messages.splice(0, messages.length, String(_message));\n break;\n }\n\n // Two rules can share a message (`string` and `email` both saying\n // \"Invalid email\"); the field reports it once (#675).\n if (!messages.includes(String(_message))) {\n messages.push(String(_message));\n }\n }\n\n if (messages.length > 0) {\n errors[key] = messages;\n }\n }\n\n for (const [key, value] of Object.entries(this.refine(input.toJSON()) ?? {})) {\n const messages = errors[key] ?? [];\n // A `refine` message the rules already reported is not repeated (#675).\n errors[key] = messages.includes(value as string) ? messages : [...messages, value as string];\n }\n\n if (Object.keys(errors).length > 0) {\n throw new ValidationError(errors);\n }\n\n return input;\n }\n\n private ruleFor(key: string, rule: string) {\n try {\n return validate(rule);\n } catch (err) {\n if (err instanceof InvalidValidationRuleError) {\n throw new InvalidValidationRuleError(\n `${this.constructor.name}.schema.${key}: ${err.message}`,\n );\n }\n throw err;\n }\n }\n\n async input(): Promise<Input<T>> {\n return this.validateInput(await this.parseBody());\n }\n\n async safeInput(): Promise<{\n isValid: boolean;\n errors: Record<string, string[]>;\n input: Input<T>;\n }> {\n const input = await this.parseBody();\n try {\n this.validateInput(input);\n return {\n isValid: true,\n errors: {},\n input,\n };\n } catch (err) {\n if (!(err instanceof ValidationError)) {\n throw err;\n }\n return {\n isValid: false,\n errors: err.errors,\n input,\n };\n }\n }\n}\n",
14
14
  "import { RequestBreakerError } from \"./Error\";\nimport { formatUnsatisfiedContentRange } from \"./range\";\n\nexport class AuthorizationError extends RequestBreakerError {\n private error: string;\n constructor(error: string = \"Not authorized\") {\n super(error);\n this.name = \"AuthorizationError\";\n this.error = error;\n this.payload = {\n api: {\n status: 401,\n data: { error: this.error },\n },\n view: {},\n };\n }\n}\n\n/**\n * A signed-in user who is not allowed to do this. Thrown by `Auth.guard()`.\n *\n * 403, not 401: a 401 tells the client to re-authenticate, so a client that\n * sends a 401 to the sign-in page would loop a signed-in user without the role\n * straight back to where they started. A request with no user at all is\n * `AuthenticationError`, which stays 401.\n */\nexport class InsufficientPermissionsError extends RequestBreakerError {\n /**\n * The status of `payload.api`, which answers API routes and `.json` view\n * navigations alike. Before 0.63 it was 401, and a shipped native client may\n * still branch on that — it cannot be rolled forward in the same deploy as\n * the server. Such an app sets this back to 401 once at boot, and removes the\n * line when its clients handle 403:\n *\n * ```ts\n * InsufficientPermissionsError.apiStatus = 401;\n * ```\n *\n * A full page load answers 403 either way; before 0.63 it fell through to\n * the view dispatcher's 400 default, which no client could have relied on.\n */\n static apiStatus: 401 | 403 = 403;\n\n private error: string;\n constructor(error: string = \"Insufficient permissions\") {\n super(error);\n this.name = \"InsufficientPermissionsError\";\n this.error = error;\n this.payload = {\n api: {\n status: InsufficientPermissionsError.apiStatus,\n data: { error: this.error },\n },\n // Without a status a view request would fall through to the\n // dispatcher's 400 default.\n view: { status: 403 },\n };\n }\n}\n\n/**\n * A `Range` that cannot be satisfied against the object's current size.\n *\n * Extends `RequestBreakerError` so a bare `FileStorage.read()` inside an\n * ordinary route still produces a correct 416 — and, importantly, so it does\n * not trip `onRequestFail`. A 416 is the client's header being wrong about the\n * object, not a server failure.\n */\nexport class RangeNotSatisfiableError extends RequestBreakerError {\n constructor(public total: number) {\n super(\"Range not satisfiable\");\n this.name = \"RangeNotSatisfiableError\";\n this.payload = {\n api: {\n status: 416,\n data: { error: { message: \"Range not satisfiable\" } },\n headers: {\n \"Content-Range\": formatUnsatisfiedContentRange(total),\n \"Accept-Ranges\": \"bytes\",\n // Decided by the client's own Range against the object's current\n // length, so it must never be replayed from a cache to a request\n // that did not ask for that window.\n \"Cache-Control\": \"no-store\",\n },\n },\n view: {},\n };\n }\n}\n\nexport class FileNotFoundError extends RequestBreakerError {\n constructor(public fileName: string) {\n super(\"File not found\");\n this.name = \"FileNotFoundError\";\n this.payload = {\n api: {\n status: 404,\n data: { error: { message: \"Not found\" } },\n headers: { \"Cache-Control\": \"no-store\" },\n },\n view: {},\n };\n }\n}\n\n/**\n * No signed-in user. A 401 to an API client; a view request is sent to\n * `redirectTo` instead — a 302 for a page load, and a `Redirect` directive for\n * a `.json` navigation, so the client router follows it rather than leaving\n * the previous page on screen.\n *\n * `redirectTo` is the whole location, intended-URL parameter included.\n * `AuthenticationMiddleware` and `Auth.user()` build it from the request and\n * the `auth.signInPath` config; code throwing this by hand can pass its own.\n */\nexport class AuthenticationError extends RequestBreakerError {\n constructor(options: { redirectTo?: string } = {}) {\n super(\"Authentication error\");\n this.name = \"AuthenticationError\";\n const location = options.redirectTo ?? \"/auth/sign-in\";\n this.payload = {\n api: {\n status: 401,\n data: { error: \"Authentication error\" },\n },\n viewData: {\n status: 200,\n data: {},\n // A refusal is per-visitor, and this one answers 200 so that\n // `loadRoutePayload` reads it at all — which makes it exactly the\n // shape a shared cache would happily store and replay to the next\n // visitor. The `view` payload below says the same thing.\n headers: {\n \"Cache-Control\": \"private, no-cache, no-store, max-age=0, must-revalidate\",\n },\n directive: { kind: \"Redirect\", path: location },\n },\n view: {\n status: 302,\n headers: {\n \"Cache-Control\":\n \"private, no-cache, no-store, max-age=0, must-revalidate\",\n Location: location,\n },\n },\n };\n }\n}\n",
15
15
  "import type { ServiceToken } from \"../container/Container\";\nimport { app } from \"../foundation/app\";\n\n/**\n * Base for the facades that front a container binding. A subclass names the\n * service it proxies with `getFacadeAccessor()` and reaches the live instance\n * through `this.getFacadeRoot()`, so the binding is resolved per call against\n * the Application for the current async context — never captured at module\n * load, which is what makes a facade swappable in tests.\n *\n * Two deliberate divergences from `Illuminate\\Support\\Facades\\Facade`:\n *\n * 1. No `__callStatic`. TypeScript has no typed equivalent, and a Proxy would\n * erase the very signatures that make these facades worth having. Subclasses\n * therefore declare explicit statics that forward to `getFacadeRoot()`.\n *\n * 2. `getFacadeAccessor()` is public, not protected. `getFacadeRoot()` types\n * its `this` structurally in order to infer the service type from the\n * accessor's return, and a protected static is not structurally assignable\n * to that.\n *\n * Facades that resolve nothing from the container — Cookie, Redirect, Url,\n * Meta — do not extend this class.\n */\nexport abstract class Facade {\n static getFacadeAccessor(): ServiceToken<any> {\n throw new Error(\n `Facade [${this.name}] does not implement getFacadeAccessor().`,\n );\n }\n\n static getFacadeRoot<T>(this: {\n getFacadeAccessor(): ServiceToken<T>;\n }): T {\n return app(this.getFacadeAccessor());\n }\n}\n",
16
16
  "import { FileNotFoundError } from \"../../../http/errors\";\nimport type {\n DeleteFileParams,\n FetchFileOptions,\n IFileStorageDriver,\n PutFileOptions,\n PutFileParams,\n ReadFileParams,\n ReadResult,\n} from \"./types\";\n\nexport abstract class FileStorageDriver implements IFileStorageDriver {\n abstract fetch(\n params: ReadFileParams | string,\n options?: FetchFileOptions,\n ): Promise<Response>;\n abstract put(\n params: PutFileParams | Blob,\n options?: PutFileOptions,\n ): Promise<string>;\n abstract list(folder: string): Promise<any>;\n\n /**\n * Removes an object. A missing object is not an error: the promise resolves,\n * so cleanup can run twice, or after a write that never landed.\n *\n * Not abstract, for the same reason `read()` is not: a custom driver written\n * before `delete()` existed keeps compiling. It must not keep *working* as if\n * it deleted, though — silently resolving here is exactly the bug `delete()`\n * used to have (#608) — so the default throws and names the driver.\n */\n async delete(_params: DeleteFileParams | string): Promise<void> {\n throw new Error(\n `${this.constructor.name} does not implement delete(). Override it to remove objects from this backend.`,\n );\n }\n\n /**\n * Default `read()` for drivers that only implement `fetch()`.\n *\n * Deliberately not abstract: every driver written before `read()` existed\n * keeps compiling and gains working range support for free. It is not\n * *efficient* though — to serve a range it buffers the whole object so the\n * framework can slice it, which saves no bandwidth from the backend. Any\n * driver whose backend can range natively should override this.\n */\n async read(input: ReadFileParams | string): Promise<ReadResult> {\n const params = typeof input === \"string\" ? { name: input } : input;\n const response = await this.fetch({\n name: params.name,\n bucket: params.bucket,\n });\n\n if (!response.ok) {\n throw new FileNotFoundError(params.name);\n }\n\n const type =\n response.headers.get(\"Content-Type\") ?? \"application/octet-stream\";\n const etag = response.headers.get(\"ETag\") ?? undefined;\n const lastModifiedHeader = response.headers.get(\"Last-Modified\");\n const lastModified = lastModifiedHeader\n ? new Date(lastModifiedHeader)\n : undefined;\n\n if (params.range) {\n const blob = await response.blob();\n return {\n body: blob,\n start: 0,\n end: blob.size - 1,\n total: blob.size,\n // The range was not applied by the backend. Reporting `false` hands\n // the slicing to `createStreamResponse`, which has the total in hand.\n partial: false,\n type,\n etag,\n lastModified,\n name: params.name,\n };\n }\n\n const contentLength = Number(response.headers.get(\"Content-Length\"));\n const total = Number.isFinite(contentLength) ? contentLength : 0;\n\n return {\n body: response.body,\n start: 0,\n end: total - 1,\n total,\n partial: false,\n type,\n etag,\n lastModified,\n name: params.name,\n };\n }\n\n /**\n * Total size of an object. Used to resolve suffix ranges on backends without\n * native suffix support, and to report the total on a 416. Override with a\n * HEAD-style request wherever one is available.\n */\n async size(params: ReadFileParams | string): Promise<number> {\n const name = typeof params === \"string\" ? params : params.name;\n const bucket = typeof params === \"string\" ? undefined : params.bucket;\n const response = await this.fetch({ name, bucket });\n if (!response.ok) {\n throw new FileNotFoundError(name);\n }\n const contentLength = Number(response.headers.get(\"Content-Length\"));\n if (Number.isFinite(contentLength)) {\n await response.body?.cancel();\n return contentLength;\n }\n return (await response.blob()).size;\n }\n}\n",
@@ -20,10 +20,10 @@
20
20
  "import type { FileStorageDriver } from \"./drivers/FileStorageDriver\";\nimport { filesystemConfigDefaults, type FilesystemConfig } from \"./config\";\n\nexport class FilesystemManager {\n static token = \"filesystem\";\n\n readonly driver: FileStorageDriver;\n\n constructor(config: FilesystemConfig = {}) {\n this.driver = config.driver ?? filesystemConfigDefaults().driver;\n }\n}\n",
21
21
  "//@ts-ignore - type-only; the module itself is loaded on first use by `metadata()`.\nimport type sharp from \"sharp\";\n\nimport { Buffer } from \"node:buffer\";\nimport { loadSharp } from \"../support/sharp\";\nimport type { Prettify } from \"../utils/type\";\n\nimport { RequestContext } from \"../http/requestContext\";\nimport type { ByteRange } from \"../http/range\";\nimport type {\n DeleteFileParams,\n FetchFileOptions,\n PutFileOptions,\n PutFileParams,\n ReadFileParams,\n ReadResult,\n} from \"../services/file-storage/drivers/types\";\nimport { FilesystemManager } from \"../services/file-storage/FilesystemManager\";\nimport { Facade } from \"./Facade\";\n\ntype Metadata = Prettify<sharp.Metadata>;\n\nexport class Storage extends Facade {\n static getFacadeAccessor() {\n return FilesystemManager;\n }\n\n /**\n * Stores a file and returns its object name. Pass `{ signal }` to cancel the\n * upload, e.g. with the incoming request's signal or `AbortSignal.timeout()`.\n */\n static async put(params: PutFileParams | Blob, options: PutFileOptions = {}) {\n return this.getFacadeRoot().driver.put(params, options);\n }\n\n static async metadata(obj: Blob | File): Promise<Partial<Metadata>> {\n const buffer = Buffer.from(await obj.arrayBuffer());\n // Outside the catch: the empty object below means \"this blob is not an\n // image sharp can read\", and a missing `sharp` install must not be able to\n // hide behind it.\n const sharp = await loadSharp(\"Storage.metadata()\");\n try {\n return await sharp(buffer).metadata();\n } catch {\n return {};\n }\n }\n\n /**\n * Reads an object as a streamed `Response`. Pass `{ signal }` to cancel the\n * read, e.g. with the incoming request's signal or `AbortSignal.timeout()`:\n * an abort rejects `fetch()` itself, or errors the body if it lands after\n * `fetch()` resolved.\n */\n static async fetch(\n params: ReadFileParams | string,\n options: FetchFileOptions = {},\n ) {\n // Checked here too, so a custom driver that predates the option still\n // refuses an already-aborted read.\n options.signal?.throwIfAborted();\n return this.getFacadeRoot().driver.fetch(params, options);\n }\n\n /**\n * Reads an object as bytes plus metadata, pushing any byte range down to the\n * storage backend so a seek transfers one window rather than the whole file.\n *\n * The range is resolved in this order: an explicit `options.range`, then a\n * `range` on `params`, then the in-flight request's `Range` header when this\n * is called inside a `this.stream()` route. Pass `{ range: null }` to force a\n * full read inside a stream route.\n */\n static async read(\n params: ReadFileParams | string,\n options: { range?: ByteRange | null } = {},\n ): Promise<ReadResult> {\n const base: ReadFileParams =\n typeof params === \"string\" ? { name: params } : { ...params };\n\n const range =\n \"range\" in options\n ? (options.range ?? null)\n : base.range !== undefined\n ? base.range\n : (RequestContext.getStore()?.rangeRequest ?? null);\n\n return this.getFacadeRoot().driver.read({\n ...base,\n range,\n });\n }\n static list(folder: string) {\n return this.getFacadeRoot().driver.list(folder);\n }\n\n /**\n * Removes a stored object. Deleting one that does not exist resolves without\n * throwing, so a cleanup path can retry safely.\n */\n static async delete(params: DeleteFileParams | string): Promise<void> {\n return this.getFacadeRoot().driver.delete(params);\n }\n}\n",
22
22
  "// @ts-ignore - `sharp` is a peer dependency; only its types are wanted here.\nimport type sharpNamespace from \"sharp\";\n\n/**\n * `sharp`, imported on first use rather than at module load.\n *\n * Three modules need it — the `Sharp` optimization driver, the `Storage` facade\n * and the OG-image branch of `ViewRouteDispatcher` — and all three are reachable\n * from the `gemi/services` and `gemi/facades` barrels, which are also the only\n * door an application has to `CronJob`, `Job`, `DB` and `Lang`. A static import\n * made every one of those imports load a native binary (#403).\n *\n * `sharp` is the only one of the four that can be genuinely absent — it is a\n * peer dependency, so an install can skip its platform binary — which is why\n * the failure gets a message naming the caller rather than a bare resolution\n * error. `usedBy` is that name, written as the caller reads in a stack trace.\n *\n * No memo: the module registry already caches a resolved `import()`, and\n * caching the *failure* would make every later call report the first call's\n * stack instead of its own.\n */\nexport async function loadSharp(usedBy: string): Promise<typeof sharpNamespace> {\n try {\n // @ts-ignore - peer dependency, resolved out of the application's own tree\n return (await import(\"sharp\")).default;\n } catch (error) {\n throw new Error(\n `${usedBy} requires the 'sharp' package. Install it with \\`bun add sharp\\`.`,\n { cause: error },\n );\n }\n}\n",
23
- "import type { FileSink } from \"bun\";\nimport { mkdir, readdir, access } from \"fs/promises\";\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\nimport { RequestContext } from \"../../http/requestContext\";\nimport { projectRoot } from \"../../support/discover\";\nimport type { LogConfig } from \"./config\";\nimport type { LogEntry, LogLevel } from \"./types\";\n\nexport class LogManager {\n static token = \"log\";\n\n writer: FileSink;\n isReady: boolean = false;\n\n private flushTimeout: Timer;\n private fileSize: number = 0;\n private writerSize: number = 0;\n private isCreatingFile: boolean = false;\n private bootPromise: Promise<void> | null = null;\n public currentLogFilePath: string;\n\n /**\n * Computed per read, not once in the constructor: `Server.start` awaits\n * `waitForBoot()` — where `LogServiceProvider.boot()` builds this directory —\n * and only *then* imports the http layer that sets `ROOT_DIR`. A field\n * initializer (or any `process.env.ROOT_DIR` read here) resolves to\n * `undefined/storage/logs` at boot, which is how every `Log.info()` ended up\n * throwing on an undefined writer. `projectRoot()` is the same rule\n * `httpProd` sets `ROOT_DIR` from, a moment later.\n */\n private get logsDirPath(): string {\n return `${projectRoot()}/storage/logs`;\n }\n\n constructor(public config: Required<LogConfig>) {}\n\n /**\n * Idempotent. `LogServiceProvider.boot()` calls this so the storage\n * directory exists before the first request; a lazy first `log()` triggers\n * it too, so the manager still works when it is resolved on its own.\n */\n boot(): Promise<void> {\n if (!this.bootPromise) {\n this.bootPromise = this.createStorage()\n .catch((err) => {\n // A logger that rejects turns every `Log.info()` into the caller's\n // error. Report the storage failure once and carry on without a file\n // sink — `log()` still feeds `onLogCreated`.\n console.error(\"Log storage unavailable, file logging disabled\", err);\n })\n .then(() => {\n this.isReady = true;\n });\n }\n return this.bootPromise;\n }\n\n private async createStorage() {\n const storageDirPath = `${projectRoot()}/storage`;\n if (!(await exists(storageDirPath))) {\n await mkdir(storageDirPath);\n }\n if (!(await exists(this.logsDirPath))) {\n await mkdir(this.logsDirPath);\n }\n await this.newLogFile();\n }\n\n async newLogFile() {\n if (!(await exists(this.logsDirPath))) {\n await mkdir(this.logsDirPath);\n }\n this.isCreatingFile = true;\n if (this.currentLogFilePath) {\n this.writer.flush();\n this.writer.end();\n this.writer = null;\n const file = new File(\n [await Bun.file(this.currentLogFilePath).arrayBuffer()],\n this.currentLogFilePath.split(\"/\").pop(),\n { type: \"text/plain\" },\n );\n this.config.onLogFileClosed(file);\n this.fileSize = 0;\n this.writerSize = 0;\n }\n\n const logFiles = await readdir(this.logsDirPath);\n\n const lastLogFile = logFiles.sort().reverse()[0];\n\n if (lastLogFile) {\n const _file = Bun.file(`${this.logsDirPath}/${lastLogFile}`);\n if (_file.size < this.config.maxFileSize) {\n this.currentLogFilePath = `${this.logsDirPath}/${lastLogFile}`;\n\n this.writer = _file.writer();\n this.writer.write(await _file.text());\n this.writer.write(\"\\n\");\n this.writer.flush();\n this.fileSize = _file.size;\n }\n }\n\n if (!this.writer) {\n const logFileName =\n `${new Date(Date.now()).toISOString()}.log`.replaceAll(\":\", \"-\");\n this.currentLogFilePath = `${this.logsDirPath}/${logFileName}`;\n const file = Bun.file(`${this.logsDirPath}/${logFileName}`);\n this.writer = file.writer();\n this.fileSize = 0;\n this.writerSize = 0;\n }\n this.isCreatingFile = false;\n }\n\n async log(\n level: LogLevel,\n message: string,\n metadata: Record<string, any> = {},\n ) {\n if (!this.isReady) {\n await this.boot();\n }\n\n const reqCtx = RequestContext.getStore();\n let requestMetadata = {};\n if (reqCtx) {\n requestMetadata = {\n url: reqCtx.req.rawRequest.url,\n method: reqCtx.req.rawRequest.method,\n headers: reqCtx.req.rawRequest.headers,\n body: reqCtx.req.rawRequest.body,\n };\n }\n\n const logObject: LogEntry = {\n timestamp: new Date(Date.now()).toISOString(),\n env: process.env.NODE_ENV,\n level,\n message,\n metadata: { ...requestMetadata, ...metadata },\n };\n\n let log = \"\";\n try {\n log = JSON.stringify(logObject);\n } catch (err) {\n console.log(\"Error parsing log object\", err);\n }\n // Broadcast.channel(\"/logs/live\", {}).publish(JSON.stringify(logObject));\n //\n // Contained, because this is an app-supplied hook and every facade method\n // calls `log()` without awaiting it: a hook that throws would otherwise\n // leave a floating `Log.info()` as an unhandled rejection, which is the\n // failure this method exists to not have. A rejected promise from an async\n // hook is the same thing arriving later, so it is caught too — what is not\n // done is *awaiting* it, which would put the app's transport in front of\n // the file write.\n try {\n const handled = this.config.onLogCreated(logObject);\n if (handled instanceof Promise) {\n handled.catch((err) => console.error(\"Error in onLogCreated\", err));\n }\n } catch (err) {\n console.error(\"Error in onLogCreated\", err);\n }\n\n // No writer means `createStorage` failed (or a rotation is mid-flight);\n // either way the entry has already been handed to `onLogCreated`, so drop\n // the file copy rather than throwing at the call site.\n if (!this.writer) {\n return;\n }\n\n this.writerSize += log.length;\n this.fileSize += log.length;\n\n try {\n this.writer.write(log);\n this.writer.write(\"\\n\");\n this.tryFlush();\n } catch (err) {\n console.error(\"Error writing log\", err);\n // Do something\n }\n }\n\n async tryFlush() {\n if (this.fileSize > this.config.maxFileSize) {\n if (!this.isCreatingFile) {\n await this.newLogFile();\n }\n }\n if (this.writerSize > this.config.maxFileSize / 2) {\n await this.writer.flush();\n this.writerSize = 0;\n await this.newLogFile();\n } else {\n clearTimeout(this.flushTimeout);\n this.flushTimeout = setTimeout(async () => {\n await this.writer.flush();\n this.writerSize = 0;\n }, 100);\n }\n }\n}\n",
23
+ "import type { FileSink } from \"bun\";\nimport { mkdir, readdir, access } from \"fs/promises\";\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\nimport { RequestContext } from \"../../http/requestContext\";\nimport { projectRoot } from \"../../support/discover\";\nimport type { LogConfig } from \"./config\";\nimport type { LogEntry, LogLevel } from \"./types\";\n\nexport class LogManager {\n static token = \"log\";\n\n writer: FileSink;\n isReady: boolean = false;\n\n private flushTimeout: Timer;\n private fileSize: number = 0;\n private writerSize: number = 0;\n private isCreatingFile: boolean = false;\n private bootPromise: Promise<void> | null = null;\n public currentLogFilePath: string;\n\n /**\n * Computed per read, not once in the constructor: `Server.start` awaits\n * `waitForBoot()` — where `LogServiceProvider.boot()` builds this directory —\n * and only *then* imports the http layer that sets `ROOT_DIR`. A field\n * initializer (or any `process.env.ROOT_DIR` read here) resolves to\n * `undefined/storage/logs` at boot, which is how every `Log.info()` ended up\n * throwing on an undefined writer. `projectRoot()` is the same rule\n * `httpProd` sets `ROOT_DIR` from, a moment later.\n */\n private get logsDirPath(): string {\n return `${projectRoot()}/storage/logs`;\n }\n\n constructor(public config: Required<LogConfig>) {}\n\n /**\n * Idempotent. `LogServiceProvider.boot()` calls this so the storage\n * directory exists before the first request; a lazy first `log()` triggers\n * it too, so the manager still works when it is resolved on its own.\n */\n boot(): Promise<void> {\n if (!this.bootPromise) {\n this.bootPromise = this.createStorage()\n .catch((err) => {\n // A logger that rejects turns every `Log.info()` into the caller's\n // error. Report the storage failure once and carry on without a file\n // sink — `log()` still feeds `onLogCreated`.\n console.error(\"Log storage unavailable, file logging disabled\", err);\n })\n .then(() => {\n this.isReady = true;\n });\n }\n return this.bootPromise;\n }\n\n private async createStorage() {\n const storageDirPath = `${projectRoot()}/storage`;\n if (!(await exists(storageDirPath))) {\n await mkdir(storageDirPath);\n }\n if (!(await exists(this.logsDirPath))) {\n await mkdir(this.logsDirPath);\n }\n await this.newLogFile();\n }\n\n async newLogFile() {\n if (!(await exists(this.logsDirPath))) {\n await mkdir(this.logsDirPath);\n }\n this.isCreatingFile = true;\n if (this.currentLogFilePath) {\n this.writer.flush();\n this.writer.end();\n this.writer = null;\n const file = new File(\n [await Bun.file(this.currentLogFilePath).arrayBuffer()],\n this.currentLogFilePath.split(\"/\").pop(),\n { type: \"text/plain\" },\n );\n this.config.onLogFileClosed(file);\n this.fileSize = 0;\n this.writerSize = 0;\n }\n\n const logFiles = await readdir(this.logsDirPath);\n\n const lastLogFile = logFiles.sort().reverse()[0];\n\n if (lastLogFile) {\n const _file = Bun.file(`${this.logsDirPath}/${lastLogFile}`);\n if (_file.size < this.config.maxFileSize) {\n this.currentLogFilePath = `${this.logsDirPath}/${lastLogFile}`;\n\n this.writer = _file.writer();\n this.writer.write(await _file.text());\n this.writer.write(\"\\n\");\n this.writer.flush();\n this.fileSize = _file.size;\n }\n }\n\n if (!this.writer) {\n const logFileName =\n `${new Date(Date.now()).toISOString()}.log`.replaceAll(\":\", \"-\");\n this.currentLogFilePath = `${this.logsDirPath}/${logFileName}`;\n const file = Bun.file(`${this.logsDirPath}/${logFileName}`);\n this.writer = file.writer();\n this.fileSize = 0;\n this.writerSize = 0;\n }\n this.isCreatingFile = false;\n }\n\n async log(\n level: LogLevel,\n message: string,\n metadata: Record<string, any> = {},\n ) {\n if (!this.isReady) {\n await this.boot();\n }\n\n const reqCtx = RequestContext.getStore();\n let requestMetadata = {};\n if (reqCtx) {\n requestMetadata = {\n url: reqCtx.req.rawRequest.url,\n method: reqCtx.req.rawRequest.method,\n headers: reqCtx.req.rawRequest.headers,\n body: reqCtx.req.rawRequest.body,\n };\n }\n\n const logObject: LogEntry = {\n timestamp: new Date(Date.now()).toISOString(),\n env: process.env.NODE_ENV,\n level,\n message,\n metadata: { ...requestMetadata, ...metadata },\n };\n\n let log = \"\";\n try {\n log = JSON.stringify(logObject);\n } catch (err) {\n console.log(\"Error parsing log object\", err);\n }\n // Contained, because this is an app-supplied hook and every facade method\n // calls `log()` without awaiting it: a hook that throws would otherwise\n // leave a floating `Log.info()` as an unhandled rejection, which is the\n // failure this method exists to not have. A rejected promise from an async\n // hook is the same thing arriving later, so it is caught too — what is not\n // done is *awaiting* it, which would put the app's transport in front of\n // the file write.\n try {\n const handled = this.config.onLogCreated(logObject);\n if (handled instanceof Promise) {\n handled.catch((err) => console.error(\"Error in onLogCreated\", err));\n }\n } catch (err) {\n console.error(\"Error in onLogCreated\", err);\n }\n\n // No writer means `createStorage` failed (or a rotation is mid-flight);\n // either way the entry has already been handed to `onLogCreated`, so drop\n // the file copy rather than throwing at the call site.\n if (!this.writer) {\n return;\n }\n\n this.writerSize += log.length;\n this.fileSize += log.length;\n\n try {\n this.writer.write(log);\n this.writer.write(\"\\n\");\n this.tryFlush();\n } catch (err) {\n console.error(\"Error writing log\", err);\n // Do something\n }\n }\n\n async tryFlush() {\n if (this.fileSize > this.config.maxFileSize) {\n if (!this.isCreatingFile) {\n await this.newLogFile();\n }\n }\n if (this.writerSize > this.config.maxFileSize / 2) {\n await this.writer.flush();\n this.writerSize = 0;\n await this.newLogFile();\n } else {\n clearTimeout(this.flushTimeout);\n this.flushTimeout = setTimeout(async () => {\n await this.writer.flush();\n this.writerSize = 0;\n }, 100);\n }\n }\n}\n",
24
24
  "import { LogManager } from \"../services/logging/LogManager\";\nimport { Facade } from \"./Facade\";\n\nexport class Log extends Facade {\n static getFacadeAccessor() {\n return LogManager;\n }\n\n static debug(message: string, metadata?: Record<string, any>) {\n this.getFacadeRoot().log(\"debug\", message, metadata);\n }\n\n static info(message: string, metadata?: Record<string, any>) {\n this.getFacadeRoot().log(\"info\", message, metadata);\n }\n\n static notice(message: string, metadata?: Record<string, any>) {\n this.getFacadeRoot().log(\"notice\", message, metadata);\n }\n\n static warning(message: string, metadata?: Record<string, any>) {\n this.getFacadeRoot().log(\"warning\", message, metadata);\n }\n\n static error(message: string, metadata?: Record<string, any>) {\n this.getFacadeRoot().log(\"error\", message, metadata);\n }\n\n static critical(message: string, metadata?: Record<string, any>) {\n this.getFacadeRoot().log(\"critical\", message, metadata);\n }\n\n static alert(message: string, metadata?: Record<string, any>) {\n this.getFacadeRoot().log(\"alert\", message, metadata);\n }\n\n static emergency(message: string, metadata?: Record<string, any>) {\n this.getFacadeRoot().log(\"emergency\", message, metadata);\n }\n}\n"
25
25
  ],
26
- "mappings": "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",
27
- "debugId": "C06EF1FC40EB69B364756E2164756E21",
26
+ "mappings": ";uLAEO,AAAM,LAAW,CACf,MAAO,aAEd,WAAW,EAAG,EAChB,CAIO,MAAe,UAA2B,CAAW,CAM5D,CCFO,SAAS,CAAiB,CAAC,EAAwD,CACxF,IAAM,EAAU,IAAI,IACpB,GAAI,CAAC,EACH,OAAO,EAET,QAAW,KAAQ,EAAO,MAAM,GAAG,EAAG,CACpC,IAAM,EAAK,EAAK,QAAQ,GAAG,EAC3B,GAAI,IAAO,GAAI,SACf,IAAM,EAAO,EAAK,MAAM,EAAG,CAAE,EAAE,KAAK,EACpC,GAAI,CAAC,EAAM,SACX,EAAQ,IAAI,EAAM,EAAK,MAAM,EAAK,CAAC,EAAE,KAAK,CAAC,EAE7C,OAAO,EAGF,SAAS,EAAU,CAAC,EAAmC,CAC5D,OAAO,EAAkB,EAAI,QAAQ,IAAI,QAAQ,CAAC,ECTpD,SAAS,CAAY,CAAC,EAA4B,CAGhD,GAAI,CAAC,QAAQ,KAAK,CAAG,EACnB,OAAO,KAET,IAAM,EAAQ,OAAO,CAAG,EACxB,OAAO,OAAO,cAAc,CAAK,EAAI,EAAQ,KAcxC,SAAS,CAAgB,CAC9B,EACkB,CAClB,GAAI,CAAC,EACH,OAAO,KAGT,IAAM,EAAU,EAAO,KAAK,EAC5B,GAAI,CAAC,WAAW,KAAK,CAAO,EAC1B,OAAO,KAUT,IAAM,EAPQ,EACX,MAAM,CAAe,EACrB,MAAM,GAAG,EACT,IAAI,CAAC,IAAS,EAAK,KAAK,CAAC,EAIN,OAAO,CAAC,IAAS,IAAS,EAAE,EAClD,GAAI,EAAQ,SAAW,EACrB,OAAO,KAGT,IAAM,EAAO,EAAQ,GACf,EAAY,EAAK,QAAQ,GAAG,EAClC,GAAI,IAAc,GAChB,OAAO,KAGT,IAAM,EAAW,EAAK,MAAM,EAAG,CAAS,EAClC,EAAS,EAAK,MAAM,EAAY,CAAC,EAEvC,GAAI,IAAa,GAAI,CAEnB,IAAM,EAAe,EAAa,CAAM,EACxC,GAAI,IAAiB,KACnB,OAAO,KAKT,MAAO,CAAE,KAAM,SAAU,cAAa,EAGxC,IAAM,EAAQ,EAAa,CAAQ,EACnC,GAAI,IAAU,KACZ,OAAO,KAGT,GAAI,IAAW,GACb,MAAO,CAAE,KAAM,SAAU,QAAO,IAAK,IAAK,EAG5C,IAAM,EAAM,EAAa,CAAM,EAC/B,GAAI,IAAQ,MAAQ,EAAM,EACxB,OAAO,KAGT,MAAO,CAAE,KAAM,SAAU,QAAO,KAAI,EAS/B,SAAS,CAAY,CAC1B,EACA,EACsB,CAGtB,GAAI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,EACtC,OAAO,KAGT,IAAI,EACA,EAEJ,GAAI,EAAM,OAAS,SAAU,CAC3B,GAAI,EAAM,cAAgB,EACxB,OAAO,KAET,EAAQ,KAAK,IAAI,EAAG,EAAQ,EAAM,YAAY,EAC9C,EAAM,EAAQ,EACT,KACL,GAAI,EAAM,OAAS,EACjB,OAAO,KAMT,GAJA,EAAQ,EAAM,MAGd,EAAM,EAAM,MAAQ,KAAO,EAAQ,EAAI,KAAK,IAAI,EAAM,IAAK,EAAQ,CAAC,EAChE,EAAM,EACR,OAAO,KAIX,MAAO,CAAE,QAAO,MAAK,OAAQ,EAAM,EAAQ,CAAE,EAIxC,SAAS,EAAkB,CAAC,EAA0B,CAC3D,GAAI,EAAM,OAAS,SACjB,MAAO,UAAU,EAAM,eAEzB,OAAO,EAAM,MAAQ,KACjB,SAAS,EAAM,SACf,SAAS,EAAM,SAAS,EAAM,MAU7B,SAAS,EAAiB,CAC/B,EACqB,CACrB,GAAI,CAAC,EACH,OAAO,KAET,IAAM,EAAQ,gCAAgC,KAAK,EAAM,KAAK,CAAC,EAC/D,GAAI,CAAC,EACH,OAAO,KAET,IAAM,EAAQ,EAAa,EAAM,EAAE,EAC7B,EAAM,EAAa,EAAM,EAAE,EAC3B,EAAQ,EAAa,EAAM,EAAE,EACnC,GAAI,IAAU,MAAQ,IAAQ,MAAQ,IAAU,MAAQ,EAAM,EAC5D,OAAO,KAET,MAAO,CAAE,QAAO,MAAK,OAAM,EAGtB,SAAS,EAAkB,CAChC,EACA,EACA,EACQ,CACR,MAAO,SAAS,KAAS,KAAO,IAI3B,SAAS,CAA6B,CAAC,EAAuB,CACnE,MAAO,WAAW,IC/Lb,IAAM,GAA6B,6BAEnC,MAAM,UAA4B,KAAM,CACtC,KAHiC,6BAIjC,QASH,CAAE,IAAK,CAAC,EAAG,KAAM,CAAC,CAAE,CAC1B,CCIO,MAAM,UAAwB,CAAoB,CACvD,OAAmC,CAAC,EACpC,WAAW,CAAC,EAAkC,CAC5C,MAAM,kBAAkB,EACxB,KAAK,KAAO,kBACZ,KAAK,OAAS,EACd,KAAK,QAAU,CACb,IAAK,CACH,OAAQ,IACR,KAAM,CACJ,MAAO,CACL,KAAM,mBACN,SAAU,CACZ,CACF,EACA,QAAS,CACP,eAAgB,kBAClB,CACF,EACA,KAAM,CACJ,OAAQ,GACV,CACF,EAEJ,CClBA,SAAS,CAAmB,CAAC,EAAc,CACzC,IAAO,EAAQ,GAAQ,EAAK,MAAM,UAAU,GAAK,CAAC,EAClD,GAAI,CAAC,GAAU,CAAC,EACd,MAAO,GAET,IAAM,EAAW,OAAO,SAAS,CAAM,EACvC,OAAQ,OACD,IACH,OAAO,MACJ,KACH,OAAO,EAAW,SACf,KACH,OAAO,EAAW,KAAO,SACtB,KACH,OAAO,EAAW,KAAO,KAAO,SAC7B,KACH,OAAO,EAAW,KAAO,KAAO,KAAO,aAEvC,MAAO,IAMb,SAAS,CAAmB,CAAC,EAAc,CACzC,OAAQ,OACD,QACH,MAAO,YACJ,MACH,MAAO,gBACJ,MACH,MAAO,iBACJ,OACH,MAAO,iBACJ,MACH,MAAO,eACJ,QACH,MAAO,wEACJ,MACH,MAAO,eACJ,OACH,MAAO,8EACJ,MACH,MAAO,sBACJ,OACH,MAAO,2BAEP,OAAO,GAMb,SAAS,CAAQ,CAAC,EAAgC,CAChD,GAAI,OAAO,IAAU,UAAY,MAAM,QAAQ,CAAK,EAAG,OAAO,EAAM,OACpE,OAGF,SAAS,CAAQ,CAAC,EAA6B,CAC7C,OAAO,OAAO,IAAU,UAAY,CAAC,OAAO,MAAM,CAAK,EAMlD,IAAM,EAAQ,CACnB,WACA,SACA,UACA,SACA,QACA,WACA,MACA,MACA,MACA,MACA,OACA,WACA,UACF,EAOO,MAAM,UAAmC,KAAM,CACpD,KAAO,4BACT,CAIA,SAAS,CAAY,CAAC,EAAc,EAAmC,CACrE,IAAM,EAAI,IAAU,QAAa,EAAM,KAAK,IAAM,GAAK,OAAO,IAAM,OAAO,CAAK,EAChF,GAAI,OAAO,MAAM,CAAC,EAChB,MAAM,IAAI,EACR,oBAAoB,KAAQ,GAAS,6BAA6B,MACpE,EAEF,OAAO,EAGF,SAAS,CAAQ,CAAC,EAAkB,CACzC,IAAO,EAAM,GAAS,EAAS,MAAM,GAAG,EACxC,OAAQ,OAoBD,WACH,MAAO,CAAC,IAAe,CACrB,GAAI,aAAiB,KACnB,OAAO,EAAM,KAAO,EAEtB,GAAI,IAAU,MAAQ,IAAU,OAC9B,MAAO,GAET,GAAI,OAAO,IAAU,UAAY,MAAM,QAAQ,CAAK,EAClD,OAAO,EAAM,OAAS,EAExB,MAAO,QAQN,SACH,MAAO,CAAC,IAAe,OAAO,IAAU,aACrC,UACH,MAAO,CAAC,IAAe,OAAO,IAAU,cACrC,SACH,MAAO,CAAC,IAAe,EAAS,CAAK,MAMlC,WACH,MAAO,CAAC,IAAe,CAMrB,OAAO,OAAO,IAAU,UADF,0DAC4B,KAAK,CAAK,OAgB3D,MAAO,CACV,IAAM,EAAM,EAAa,EAAM,CAAK,EACpC,MAAO,CAAC,IAAe,CACrB,IAAM,EAAS,EAAS,CAAK,EAC7B,OAAO,IAAW,QAAa,GAAU,EAE7C,KACK,MAAO,CACV,IAAM,EAAM,EAAa,EAAM,CAAK,EACpC,MAAO,CAAC,IAAe,CACrB,IAAM,EAAS,EAAS,CAAK,EAC7B,OAAO,IAAW,QAAa,GAAU,EAE7C,KAEK,MAAO,CACV,IAAM,EAAQ,EAAa,EAAM,CAAK,EACtC,MAAO,CAAC,IAAe,EAAS,CAAK,GAAK,GAAS,CACrD,KACK,MAAO,CACV,IAAM,EAAQ,EAAa,EAAM,CAAK,EACtC,MAAO,CAAC,IAAe,EAAS,CAAK,GAAK,GAAS,CACrD,KACK,QACH,MAAO,CAAC,IAAe,CAErB,OAAO,OAAO,IAAU,UADL,6BAC4B,KAAK,CAAK,OAExD,OACH,MAAO,CAAC,IAAe,CACrB,OAAO,aAAiB,UAEvB,WAAY,CACf,GAAI,CAAC,EACH,MAAM,IAAI,EACR,kFACF,EAEF,IAAM,EAAa,EAAoB,CAAK,EAC5C,MAAO,CAAC,IAAe,aAAiB,MAAQ,EAAM,KAAK,WAAW,CAAU,CAClF,KACK,WAAY,CAIf,IAAM,EAAe,EAAoB,GAAS,EAAE,EACpD,GAAI,IAAiB,GAAK,CAAC,sBAAsB,KAAK,GAAS,EAAE,EAC/D,MAAM,IAAI,EACR,6BAA6B,GAAS,oEACxC,EAEF,MAAO,CAAC,IAAe,aAAiB,MAAQ,EAAM,MAAQ,CAChE,SAQE,MAAM,IAAI,EACR,4BAA4B,oBAA2B,EAAM,KAAK,IAAI,GACxE,GChPN,IAAM,EAAa,IAAI,QAMhB,SAAS,EAAmB,CAAC,EAAc,EAAuB,CACvE,EAAW,IAAI,EAAK,CAAE,eAAc,CAAC,EAGhC,SAAS,CAAiB,CAAC,EAAuB,CACvD,OAAO,EAAW,IAAI,CAAG,EAgBpB,SAAS,EAAuB,CAAC,EAAkC,CACxE,OAAO,EAAW,IAAI,CAAG,GAAG,cC5C9B,IAAM,EAAU,IAAI,QAEb,SAAS,EAAgB,CAAC,EAAc,EAAwB,CACrE,EAAQ,IAAI,EAAK,CAAM,EAIlB,SAAS,CAAa,CAAC,EAAqC,CACjE,OAAO,EAAQ,IAAI,CAAG,GAAK,KAK7B,IAAM,EAAW,IAAI,QAEd,SAAS,EAAoB,CAAC,EAAc,EAAgB,CACjE,IAAM,EAAU,EAAS,IAAI,CAAG,GAAK,CAAC,EACtC,GAAI,CAAC,EAAQ,SAAS,CAAM,EAC1B,EAAS,IAAI,EAAK,CAAC,GAAG,EAAS,CAAM,CAAC,EAKnC,SAAS,EAAoB,CAAC,EAAiC,CACpE,OAAO,EAAS,IAAI,CAAG,GAAK,CAAC,ECtB/B,MAAM,CAAS,CACO,KAApB,WAAW,CAAS,EAAS,CAAT,YAEb,GAAsB,CAAC,EAAc,CAC1C,OAAO,KAAK,KAAK,GAGZ,GAAG,CAAC,EAAc,CACvB,OAAO,KAAK,KAAK,KAAS,OAGrB,MAAM,EAAM,CACjB,OAAO,KAAK,KAEhB,CA2CO,MAAM,EAAoF,CAC/F,KACA,WACA,QACA,QACA,OACA,OAAc,CAAC,EACf,UACA,OAQA,OAEA,WAAW,CAAC,EAAe,EAAc,EAAwB,EAAoB,CACnF,GAAI,CAAC,EAAK,CACR,IAAM,EAAO,EAAe,SAAS,EAAE,IACvC,KAAK,OAAS,EAAK,OACnB,KAAK,WAAa,EAAK,WACvB,KAAK,KAAO,EAAK,KACjB,KAAK,UAAY,EAAK,UACtB,KAAK,OAAS,EAAK,QAAU,KAE7B,UAAK,OAAS,EACd,KAAK,WAAa,EAClB,KAAK,UAAY,EACjB,KAAK,KAAO,GAAQ,MACpB,KAAK,OAAS,EAAc,CAAG,EAGjC,KAAK,QAAU,KAAK,WAAW,QAE/B,IAAM,EAAU,EAAkB,KAAK,WAAW,QAAQ,IAAI,QAAQ,CAAC,EACjE,EAAM,IAAI,IAAI,KAAK,WAAW,GAAG,EACjC,EAAM,IAAI,IAChB,QAAY,EAAK,KAAU,EAAI,aAC7B,GAAI,EAAI,IAAI,CAAG,EAAG,CAChB,IAAM,EAAe,EAAI,IAAI,CAAG,EAChC,GAAI,MAAM,QAAQ,CAAY,EAC5B,EAAa,KAAK,CAAK,EACvB,EAAI,IAAI,EAAK,CAAY,EAEzB,OAAI,IAAI,EAAK,CAAC,EAAc,CAAK,CAAC,EAGpC,OAAI,IAAI,EAAK,CAAK,EAGtB,IAAM,EAAU,OAAO,YAAY,EAAI,QAAQ,CAAC,EAChD,KAAK,OAAS,IAAI,EAAM,CAAO,EAC/B,KAAK,QAAU,EAGjB,MAAM,EAAG,CACP,OAAO,EAAe,SAAS,EAAE,OAGnC,GAAG,EAAG,CACJ,OAAO,EAAe,SAAS,EAUjC,iBAAiB,EAAY,CAC3B,OAAO,EAAkB,KAAK,UAAU,EAQ1C,KAAK,EAAG,CACN,OAAO,EAAiB,KAAK,WAAW,QAAQ,IAAI,OAAO,CAAC,EAG9D,MAAM,CAAC,EAAkB,CACvB,MAAO,CAAC,OAGI,UAAS,EAAG,CACxB,IAAI,EAAW,IAAI,EAAS,CAAC,CAAM,EACnC,GAAI,KAAK,WAAW,QAAQ,IAAI,cAAc,IAAM,mBAAoB,CACtE,IAAM,EAAO,MAAM,KAAK,WAAW,KAAK,EACxC,EAAW,IAAI,EAAS,CAAS,EAEnC,GAAI,KAAK,WAAW,QAAQ,IAAI,cAAc,IAAM,oCAAqC,CACvF,IAAM,EAAQ,MAAM,KAAK,WAAW,SAAS,EAC7C,EAAW,IAAI,EAAS,CAAS,EAGnC,GAAI,KAAK,WAAW,QAAQ,IAAI,cAAc,GAAG,WAAW,qBAAqB,EAAG,CAClF,IAAM,EAAQ,MAAM,KAAK,WAAW,SAAS,EACvC,EAAY,IAAI,IACtB,QAAY,EAAK,KAAU,EAAK,QAAQ,EACtC,GAAI,EAAU,IAAI,CAAG,EAAG,CACtB,IAAM,EAAe,EAAU,IAAI,CAAG,EACtC,GAAI,MAAM,QAAQ,CAAY,EAC5B,EAAa,KAAK,CAAK,EACvB,EAAU,IAAI,EAAK,CAAY,EAE/B,OAAU,IAAI,EAAK,CAAC,EAAc,CAAK,CAAQ,EAGjD,OAAU,IAAI,EAAK,CAAmB,EAG1C,EAAW,IAAI,EAAS,OAAO,YAAY,EAAU,QAAQ,CAAC,CAAM,EAEtE,OAAO,EAGD,aAAa,CAAC,EAAiB,CACrC,IAAM,EAAmC,CAAC,EACpC,EAAS,OAAO,QAAQ,KAAK,MAAiD,EAAE,IACpF,EAAE,EAAK,MAAY,CACjB,MAKA,MAAO,OAAO,QAAQ,CAAK,EAAE,IAAI,EAAE,EAAM,MAAc,CACrD,OACA,UACA,MAAO,OAAO,IAAY,WAAa,KAAO,KAAK,QAAQ,EAAK,CAAI,CACtE,EAAE,CACJ,EACF,EAEA,QAAa,MAAK,WAAW,EAAQ,CACnC,IAAM,EAAQ,EAAM,IAAI,CAAc,EAChC,EAAa,EAAM,KAAK,EAAG,UAAW,IAAS,UAAU,EAIzD,EAAW,IAAU,QAAa,IAAU,MAAS,IAAsB,GAC3E,EAAqB,CAAC,EAE5B,QAAa,OAAM,UAAS,WAAW,EAAO,CAC5C,IAAI,EAAW,EACX,EAAW,GACf,GAAI,OAAO,IAAY,WACrB,EAAW,EAAQ,CAAK,EACxB,EAAW,OAAO,EAAa,IAE/B,OAAW,EAAO,CAAK,EAGzB,GAAI,EACF,SAGF,GAAI,GAAY,CAAC,EACf,SAGF,GAAI,IAAS,WAAY,CAIvB,EAAS,OAAO,EAAG,EAAS,OAAQ,OAAO,CAAQ,CAAC,EACpD,MAKF,GAAI,CAAC,EAAS,SAAS,OAAO,CAAQ,CAAC,EACrC,EAAS,KAAK,OAAO,CAAQ,CAAC,EAIlC,GAAI,EAAS,OAAS,EACpB,EAAO,GAAO,EAIlB,QAAY,EAAK,KAAU,OAAO,QAAQ,KAAK,OAAO,EAAM,OAAO,CAAC,GAAK,CAAC,CAAC,EAAG,CAC5E,IAAM,EAAW,EAAO,IAAQ,CAAC,EAEjC,EAAO,GAAO,EAAS,SAAS,CAAe,EAAI,EAAW,CAAC,GAAG,EAAU,CAAe,EAG7F,GAAI,OAAO,KAAK,CAAM,EAAE,OAAS,EAC/B,MAAM,IAAI,EAAgB,CAAM,EAGlC,OAAO,EAGD,OAAO,CAAC,EAAa,EAAc,CACzC,GAAI,CACF,OAAO,EAAS,CAAI,EACpB,MAAO,EAAK,CACZ,GAAI,aAAe,EACjB,MAAM,IAAI,EACR,GAAG,KAAK,YAAY,eAAe,MAAQ,EAAI,SACjD,EAEF,MAAM,QAIJ,MAAK,EAAsB,CAC/B,OAAO,KAAK,cAAc,MAAM,KAAK,UAAU,CAAC,OAG5C,UAAS,EAIZ,CACD,IAAM,EAAQ,MAAM,KAAK,UAAU,EACnC,GAAI,CAEF,OADA,KAAK,cAAc,CAAK,EACjB,CACL,QAAS,GACT,OAAQ,CAAC,EACT,OACF,EACA,MAAO,EAAK,CACZ,GAAI,EAAE,aAAe,GACnB,MAAM,EAER,MAAO,CACL,QAAS,GACT,OAAQ,EAAI,OACZ,OACF,GAGN,CC9SO,MAAM,WAA2B,CAAoB,CAClD,MACR,WAAW,CAAC,EAAgB,iBAAkB,CAC5C,MAAM,CAAK,EACX,KAAK,KAAO,qBACZ,KAAK,MAAQ,EACb,KAAK,QAAU,CACb,IAAK,CACH,OAAQ,IACR,KAAM,CAAE,MAAO,KAAK,KAAM,CAC5B,EACA,KAAM,CAAC,CACT,EAEJ,CAUO,MAAM,UAAqC,CAAoB,OAe7D,WAAuB,IAEtB,MACR,WAAW,CAAC,EAAgB,2BAA4B,CACtD,MAAM,CAAK,EACX,KAAK,KAAO,+BACZ,KAAK,MAAQ,EACb,KAAK,QAAU,CACb,IAAK,CACH,OAAQ,EAA6B,UACrC,KAAM,CAAE,MAAO,KAAK,KAAM,CAC5B,EAGA,KAAM,CAAE,OAAQ,GAAI,CACtB,EAEJ,CAUO,MAAM,UAAiC,CAAoB,CAC7C,MAAnB,WAAW,CAAQ,EAAe,CAChC,MAAM,uBAAuB,EADZ,aAEjB,KAAK,KAAO,2BACZ,KAAK,QAAU,CACb,IAAK,CACH,OAAQ,IACR,KAAM,CAAE,MAAO,CAAE,QAAS,uBAAwB,CAAE,EACpD,QAAS,CACP,gBAAiB,EAA8B,CAAK,EACpD,gBAAiB,QAIjB,gBAAiB,UACnB,CACF,EACA,KAAM,CAAC,CACT,EAEJ,CAEO,MAAM,UAA0B,CAAoB,CACtC,SAAnB,WAAW,CAAQ,EAAkB,CACnC,MAAM,gBAAgB,EADL,gBAEjB,KAAK,KAAO,oBACZ,KAAK,QAAU,CACb,IAAK,CACH,OAAQ,IACR,KAAM,CAAE,MAAO,CAAE,QAAS,WAAY,CAAE,EACxC,QAAS,CAAE,gBAAiB,UAAW,CACzC,EACA,KAAM,CAAC,CACT,EAEJ,CAYO,MAAM,WAA4B,CAAoB,CAC3D,WAAW,CAAC,EAAmC,CAAC,EAAG,CACjD,MAAM,sBAAsB,EAC5B,KAAK,KAAO,sBACZ,IAAM,EAAW,EAAQ,YAAc,gBACvC,KAAK,QAAU,CACb,IAAK,CACH,OAAQ,IACR,KAAM,CAAE,MAAO,sBAAuB,CACxC,EACA,SAAU,CACR,OAAQ,IACR,KAAM,CAAC,EAKP,QAAS,CACP,gBAAiB,yDACnB,EACA,UAAW,CAAE,KAAM,WAAY,KAAM,CAAS,CAChD,EACA,KAAM,CACJ,OAAQ,IACR,QAAS,CACP,gBACE,0DACF,SAAU,CACZ,CACF,CACF,EAEJ,CC5HO,MAAe,CAAO,OACpB,kBAAiB,EAAsB,CAC5C,MAAU,MACR,WAAW,KAAK,+CAClB,QAGK,cAAgB,EAEjB,CACJ,OAAO,EAAI,KAAK,kBAAkB,CAAC,EAEvC,CCzBO,MAAe,CAAgD,MAoB9D,OAAM,CAAC,EAAmD,CAC9D,MAAU,MACR,GAAG,KAAK,YAAY,oFACtB,OAYI,KAAI,CAAC,EAAqD,CAC9D,IAAM,EAAS,OAAO,IAAU,SAAW,CAAE,KAAM,CAAM,EAAI,EACvD,EAAW,MAAM,KAAK,MAAM,CAChC,KAAM,EAAO,KACb,OAAQ,EAAO,MACjB,CAAC,EAED,GAAI,CAAC,EAAS,GACZ,MAAM,IAAI,EAAkB,EAAO,IAAI,EAGzC,IAAM,EACJ,EAAS,QAAQ,IAAI,cAAc,GAAK,2BACpC,EAAO,EAAS,QAAQ,IAAI,MAAM,GAAK,OACvC,EAAqB,EAAS,QAAQ,IAAI,eAAe,EACzD,EAAe,EACjB,IAAI,KAAK,CAAkB,EAC3B,OAEJ,GAAI,EAAO,MAAO,CAChB,IAAM,EAAO,MAAM,EAAS,KAAK,EACjC,MAAO,CACL,KAAM,EACN,MAAO,EACP,IAAK,EAAK,KAAO,EACjB,MAAO,EAAK,KAGZ,QAAS,GACT,OACA,OACA,eACA,KAAM,EAAO,IACf,EAGF,IAAM,EAAgB,OAAO,EAAS,QAAQ,IAAI,gBAAgB,CAAC,EAC7D,EAAQ,OAAO,SAAS,CAAa,EAAI,EAAgB,EAE/D,MAAO,CACL,KAAM,EAAS,KACf,MAAO,EACP,IAAK,EAAQ,EACb,QACA,QAAS,GACT,OACA,OACA,eACA,KAAM,EAAO,IACf,OAQI,KAAI,CAAC,EAAkD,CAC3D,IAAM,EAAO,OAAO,IAAW,SAAW,EAAS,EAAO,KACpD,EAAS,OAAO,IAAW,SAAW,OAAY,EAAO,OACzD,EAAW,MAAM,KAAK,MAAM,CAAE,OAAM,QAAO,CAAC,EAClD,GAAI,CAAC,EAAS,GACZ,MAAM,IAAI,EAAkB,CAAI,EAElC,IAAM,EAAgB,OAAO,EAAS,QAAQ,IAAI,gBAAgB,CAAC,EACnE,GAAI,OAAO,SAAS,CAAa,EAE/B,OADA,MAAM,EAAS,MAAM,OAAO,EACrB,EAET,OAAQ,MAAM,EAAS,KAAK,GAAG,KAEnC,CCvGO,SAAS,CAAa,CAC3B,EACA,EAC4B,CAC5B,GAAI,CAAC,EACH,OAAO,EAGT,IAAM,EAAS,EAAK,UAAU,EAC1B,EAAU,GACV,EAEE,EAAS,IAAM,CAEnB,GADA,EAAU,GACN,EACF,EAAO,oBAAoB,QAAS,CAAO,GAI/C,OAAO,IAAI,eACT,CACE,KAAK,CAAC,EAAY,CAOhB,GANA,EAAU,IAAM,CACd,GAAI,EAAS,OACb,EAAO,EACP,EAAW,MAAM,EAAO,MAAM,EAC9B,EAAO,OAAO,EAAO,MAAM,EAAE,MAAM,IAAM,EAAE,GAEzC,EAAO,QACT,EAAQ,EAER,OAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,QAGtD,KAAI,CAAC,EAAY,CACrB,IAAI,EACJ,GAAI,CACF,EAAQ,MAAM,EAAO,KAAK,EAC1B,MAAO,EAAK,CACZ,GAAI,EAAS,OACb,EAAO,EACP,EAAW,MAAM,CAAG,EACpB,OAIF,GAAI,EAAS,OACb,GAAI,EAAM,KAAM,CACd,EAAO,EACP,EAAW,MAAM,EACjB,OAEF,EAAW,QAAQ,EAAM,KAAK,GAEhC,MAAM,CAAC,EAAQ,CAEb,OADA,EAAO,EACA,EAAO,OAAO,CAAM,EAE/B,EAEA,CAAE,cAAe,CAAE,CACrB,ECjEF,kBAAS,aAAS,qBAClB,qBAAS,eAAY,cAAU,SAAS,cAKjC,MAAM,UAAyB,CAAkB,CACrC,WAEjB,WAAW,CAAC,EAAqB,CAC/B,MAAM,EACN,KAAK,WAAa,KAwBR,WAAU,EAAW,CAC/B,OAAO,KAAK,YAAc,GAAG,EAAY,iBAGrC,IAAG,CAAC,GAAgC,UAA2B,CAAC,EAAG,CACvE,GAAQ,eAAe,EAEvB,IAAI,EACA,EAEJ,GAAI,aAAkB,KACpB,EAAO,EACP,EAAO,GAAG,IAAI,aAAa,KAAK,EAAO,KAAK,MAAM,GAAG,EAAE,GAAG,MAAM,GAAG,EAAE,KAErE,OAAO,EAAO,KACd,EAAO,EAAO,KAGhB,IAAM,EACJ,aAAgB,OACZ,EACA,aAAgB,MAAQ,aAAgB,KACtC,OAAO,KAAK,MAAM,EAAK,YAAY,CAAC,EACpC,GAEF,EAAO,GAAG,KAAK,cAAc,IAOnC,OAHA,GAAQ,eAAe,EACvB,MAAM,IAAI,MAAM,EAAM,CAAa,EAE5B,OAGH,MAAK,CACT,GACE,UAA6B,CAAC,EAChC,CACA,GAAQ,eAAe,EAEvB,IAAI,EAAS,QAAQ,IAAI,YACrB,EAEJ,GAAI,OAAO,IAAW,SACpB,EAAO,EAEP,OAAS,EAAO,QAAU,EAC1B,EAAO,EAAO,KAGhB,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,EAGnD,IAAM,EAAO,GAAG,KAAK,cAAc,IAC7B,EAAO,IAAI,KAAK,CAAI,EAGpB,EAAS,EAAc,IAAI,KAAK,CAAI,EAAE,OAAO,EAAG,CAAM,EACtD,EAAO,IAAI,KAAK,EAAK,YAAY,EAAE,YAAY,EAErD,OAAO,IAAI,SAAS,EAAQ,CAC1B,QAAS,CACP,eAAgB,EAAK,KACrB,iBAAkB,OAAO,EAAK,IAAI,EAClC,gBAAiB,0CAEjB,gBAAiB,CACnB,CACF,CAAC,OAGG,KAAI,CAAC,EAAqD,CAC9D,IAAM,EAAS,OAAO,IAAU,SAAW,CAAE,KAAM,CAAM,EAAI,GACrD,OAAM,QAAQ,MAAS,EAE/B,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,EAGnD,IAAM,EAAO,IAAI,KAAK,GAAG,KAAK,cAAc,GAAM,EAKlD,GAAI,CAAE,MAAM,EAAK,OAAO,EACtB,MAAM,IAAI,EAAkB,CAAI,EAGlC,IAAM,EAAQ,EAAK,KACb,EAAW,EAAQ,EAAa,EAAO,CAAK,EAAI,KAEtD,GAAI,GAAS,CAAC,EACZ,MAAM,IAAI,EAAyB,CAAK,EAG1C,IAAM,EAAQ,GAAU,OAAS,EAC3B,EAAM,EAAW,EAAS,IAAM,EAAQ,EAE9C,MAAO,CAGL,KAAM,EAAW,EAAK,MAAM,EAAO,EAAM,CAAC,EAAI,EAC9C,QACA,MACA,QACA,QAAS,QAAQ,CAAQ,EACzB,KAAM,EAAK,MAAQ,2BACnB,aAAc,IAAI,KAAK,EAAK,YAAY,EACxC,MACF,OAGI,KAAI,CAAC,EAAiC,CAC1C,IAAM,EAAO,OAAO,IAAW,SAAW,EAAS,EAAO,KACpD,EAAO,IAAI,KAAK,GAAG,KAAK,cAAc,GAAM,EAClD,GAAI,CAAE,MAAM,EAAK,OAAO,EACtB,MAAM,IAAI,EAAkB,CAAI,EAElC,OAAO,EAAK,UAGR,OAAM,CAAC,EAAmC,CAC9C,IAAM,EAAO,OAAO,IAAW,SAAW,EAAS,EAAO,KAE1D,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,EAKnD,IAAM,EAAO,EAAQ,KAAK,UAAU,EAC9B,EAAO,EAAQ,EAAM,CAAI,EACzB,EAAM,GAAS,EAAM,CAAI,EAC/B,GAAI,CAAC,GAAO,IAAQ,MAAQ,EAAI,WAAW,KAAK,IAAK,GAAK,GAAW,CAAG,EACtE,MAAU,MAAM,uBAAuB,sCAAyC,EAGlF,GAAI,CACF,MAAM,GAAO,CAAI,EACjB,MAAO,EAAU,CAEjB,GAAI,GAAK,OAAS,SAChB,OAEF,MAAM,QAIJ,KAAI,EAAG,CAGX,OAFc,MAAM,GAAQ,KAAK,UAAU,EAI/C,CChMO,SAAS,EAAsB,CACpC,EACkB,CAClB,OAAO,EAGF,SAAS,CAAwB,EAA+B,CACrE,MAAO,CACL,OAAQ,IAAI,CACd,ECdK,MAAM,CAAkB,OACtB,OAAQ,aAEN,OAET,WAAW,CAAC,EAA2B,CAAC,EAAG,CACzC,KAAK,OAAS,EAAO,QAAU,EAAyB,EAAE,OAE9D,CCRA,iBAAS,gBCkBT,eAAsB,CAAS,CAAC,EAAgD,CAC9E,GAAI,CAEF,OAAQ,KAAa,kBAAU,QAC/B,MAAO,EAAO,CACd,MAAU,MACR,GAAG,qEACH,CAAE,MAAO,CAAM,CACjB,GDPG,MAAM,WAAgB,CAAO,OAC3B,kBAAiB,EAAG,CACzB,OAAO,cAOI,IAAG,CAAC,EAA8B,EAA0B,CAAC,EAAG,CAC3E,OAAO,KAAK,cAAc,EAAE,OAAO,IAAI,EAAQ,CAAO,cAG3C,SAAQ,CAAC,EAA8C,CAClE,IAAM,EAAS,GAAO,KAAK,MAAM,EAAI,YAAY,CAAC,EAI5C,EAAQ,MAAM,EAAU,oBAAoB,EAClD,GAAI,CACF,OAAO,MAAM,EAAM,CAAM,EAAE,SAAS,EACpC,KAAM,CACN,MAAO,CAAC,eAUC,MAAK,CAChB,EACA,EAA4B,CAAC,EAC7B,CAIA,OADA,EAAQ,QAAQ,eAAe,EACxB,KAAK,cAAc,EAAE,OAAO,MAAM,EAAQ,CAAO,cAY7C,KAAI,CACf,EACA,EAAwC,CAAC,EACpB,CACrB,IAAM,EACJ,OAAO,IAAW,SAAW,CAAE,KAAM,CAAO,EAAI,IAAK,CAAO,EAExD,EACJ,UAAW,EACN,EAAQ,OAAS,KAClB,EAAK,QAAU,OACb,EAAK,MACJ,EAAe,SAAS,GAAG,cAAgB,KAEpD,OAAO,KAAK,cAAc,EAAE,OAAO,KAAK,IACnC,EACH,OACF,CAAC,QAEI,KAAI,CAAC,EAAgB,CAC1B,OAAO,KAAK,cAAc,EAAE,OAAO,KAAK,CAAM,cAOnC,OAAM,CAAC,EAAkD,CACpE,OAAO,KAAK,cAAc,EAAE,OAAO,OAAO,CAAM,EAEpD,CEtGA,gBAAS,aAAO,aAAS,qBAEzB,eAAe,CAAM,CAAC,EAAgC,CACpD,GAAI,CAEF,OADA,MAAM,GAAO,CAAI,EACV,GACP,KAAM,CACN,MAAO,IAQJ,MAAM,CAAW,CA0BH,aAzBZ,OAAQ,MAEf,OACA,QAAmB,GAEX,aACA,SAAmB,EACnB,WAAqB,EACrB,eAA0B,GAC1B,YAAoC,KACrC,sBAWK,YAAW,EAAW,CAChC,MAAO,GAAG,EAAY,iBAGxB,WAAW,CAAQ,EAA6B,CAA7B,cAOnB,IAAI,EAAkB,CACpB,GAAI,CAAC,KAAK,YACR,KAAK,YAAc,KAAK,cAAc,EACnC,MAAM,CAAC,IAAQ,CAId,QAAQ,MAAM,iDAAkD,CAAG,EACpE,EACA,KAAK,IAAM,CACV,KAAK,QAAU,GAChB,EAEL,OAAO,KAAK,iBAGA,cAAa,EAAG,CAC5B,IAAM,EAAiB,GAAG,EAAY,YACtC,GAAI,CAAE,MAAM,EAAO,CAAc,EAC/B,MAAM,EAAM,CAAc,EAE5B,GAAI,CAAE,MAAM,EAAO,KAAK,WAAW,EACjC,MAAM,EAAM,KAAK,WAAW,EAE9B,MAAM,KAAK,WAAW,OAGlB,WAAU,EAAG,CACjB,GAAI,CAAE,MAAM,EAAO,KAAK,WAAW,EACjC,MAAM,EAAM,KAAK,WAAW,EAG9B,GADA,KAAK,eAAiB,GAClB,KAAK,mBAAoB,CAC3B,KAAK,OAAO,MAAM,EAClB,KAAK,OAAO,IAAI,EAChB,KAAK,OAAS,KACd,IAAM,EAAO,IAAI,KACf,CAAC,MAAM,IAAI,KAAK,KAAK,kBAAkB,EAAE,YAAY,CAAC,EACtD,KAAK,mBAAmB,MAAM,GAAG,EAAE,IAAI,EACvC,CAAE,KAAM,YAAa,CACvB,EACA,KAAK,OAAO,gBAAgB,CAAI,EAChC,KAAK,SAAW,EAChB,KAAK,WAAa,EAKpB,IAAM,GAFW,MAAM,GAAQ,KAAK,WAAW,GAElB,KAAK,EAAE,QAAQ,EAAE,GAE9C,GAAI,EAAa,CACf,IAAM,EAAQ,IAAI,KAAK,GAAG,KAAK,eAAe,GAAa,EAC3D,GAAI,EAAM,KAAO,KAAK,OAAO,YAC3B,KAAK,mBAAqB,GAAG,KAAK,eAAe,IAEjD,KAAK,OAAS,EAAM,OAAO,EAC3B,KAAK,OAAO,MAAM,MAAM,EAAM,KAAK,CAAC,EACpC,KAAK,OAAO,MAAM;AAAA,CAAI,EACtB,KAAK,OAAO,MAAM,EAClB,KAAK,SAAW,EAAM,KAI1B,GAAI,CAAC,KAAK,OAAQ,CAChB,IAAM,EACJ,GAAG,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE,YAAY,QAAQ,WAAW,IAAK,GAAG,EACjE,KAAK,mBAAqB,GAAG,KAAK,eAAe,IACjD,IAAM,EAAO,IAAI,KAAK,GAAG,KAAK,eAAe,GAAa,EAC1D,KAAK,OAAS,EAAK,OAAO,EAC1B,KAAK,SAAW,EAChB,KAAK,WAAa,EAEpB,KAAK,eAAiB,QAGlB,IAAG,CACP,EACA,EACA,EAAgC,CAAC,EACjC,CACA,GAAI,CAAC,KAAK,QACR,MAAM,KAAK,KAAK,EAGlB,IAAM,EAAS,EAAe,SAAS,EACnC,EAAkB,CAAC,EACvB,GAAI,EACF,EAAkB,CAChB,IAAK,EAAO,IAAI,WAAW,IAC3B,OAAQ,EAAO,IAAI,WAAW,OAC9B,QAAS,EAAO,IAAI,WAAW,QAC/B,KAAM,EAAO,IAAI,WAAW,IAC9B,EAGF,IAAM,EAAsB,CAC1B,UAAW,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE,YAAY,EAC5C,IAAK,iBACL,QACA,UACA,SAAU,IAAK,KAAoB,CAAS,CAC9C,EAEI,EAAM,GACV,GAAI,CACF,EAAM,KAAK,UAAU,CAAS,EAC9B,MAAO,EAAK,CACZ,QAAQ,IAAI,2BAA4B,CAAG,EAS7C,GAAI,CACF,IAAM,EAAU,KAAK,OAAO,aAAa,CAAS,EAClD,GAAI,aAAmB,QACrB,EAAQ,MAAM,CAAC,IAAQ,QAAQ,MAAM,wBAAyB,CAAG,CAAC,EAEpE,MAAO,EAAK,CACZ,QAAQ,MAAM,wBAAyB,CAAG,EAM5C,GAAI,CAAC,KAAK,OACR,OAGF,KAAK,YAAc,EAAI,OACvB,KAAK,UAAY,EAAI,OAErB,GAAI,CACF,KAAK,OAAO,MAAM,CAAG,EACrB,KAAK,OAAO,MAAM;AAAA,CAAI,EACtB,KAAK,SAAS,EACd,MAAO,EAAK,CACZ,QAAQ,MAAM,oBAAqB,CAAG,QAKpC,SAAQ,EAAG,CACf,GAAI,KAAK,SAAW,KAAK,OAAO,aAC9B,GAAI,CAAC,KAAK,eACR,MAAM,KAAK,WAAW,EAG1B,GAAI,KAAK,WAAa,KAAK,OAAO,YAAc,EAC9C,MAAM,KAAK,OAAO,MAAM,EACxB,KAAK,WAAa,EAClB,MAAM,KAAK,WAAW,EAEtB,kBAAa,KAAK,YAAY,EAC9B,KAAK,aAAe,WAAW,SAAY,CACzC,MAAM,KAAK,OAAO,MAAM,EACxB,KAAK,WAAa,GACjB,GAAG,EAGZ,CCjNO,MAAM,WAAY,CAAO,OACvB,kBAAiB,EAAG,CACzB,OAAO,QAGF,MAAK,CAAC,EAAiB,EAAgC,CAC5D,KAAK,cAAc,EAAE,IAAI,QAAS,EAAS,CAAQ,QAG9C,KAAI,CAAC,EAAiB,EAAgC,CAC3D,KAAK,cAAc,EAAE,IAAI,OAAQ,EAAS,CAAQ,QAG7C,OAAM,CAAC,EAAiB,EAAgC,CAC7D,KAAK,cAAc,EAAE,IAAI,SAAU,EAAS,CAAQ,QAG/C,QAAO,CAAC,EAAiB,EAAgC,CAC9D,KAAK,cAAc,EAAE,IAAI,UAAW,EAAS,CAAQ,QAGhD,MAAK,CAAC,EAAiB,EAAgC,CAC5D,KAAK,cAAc,EAAE,IAAI,QAAS,EAAS,CAAQ,QAG9C,SAAQ,CAAC,EAAiB,EAAgC,CAC/D,KAAK,cAAc,EAAE,IAAI,WAAY,EAAS,CAAQ,QAGjD,MAAK,CAAC,EAAiB,EAAgC,CAC5D,KAAK,cAAc,EAAE,IAAI,QAAS,EAAS,CAAQ,QAG9C,UAAS,CAAC,EAAiB,EAAgC,CAChE,KAAK,cAAc,EAAE,IAAI,YAAa,EAAS,CAAQ,EAE3D",
27
+ "debugId": "402F43E221AB2F3A64756E2164756E21",
28
28
  "names": []
29
29
  }
@@ -1,5 +1,5 @@
1
1
  // @bun
2
2
  var j=globalThis.__GEMI_DICTIONARY_REGISTRY__??={registry:new Map,resolved:new Map,inFlight:new Map,renderThenables:new Map,order:[],warmed:new Map,activeLocale:null},{registry:W,resolved:Z,inFlight:V,renderThenables:I,order:E,warmed:X}=j;function N(q,x){return`${q}\x00${x}`}function D(q){if(W.has(q.id))return;W.set(q.id,q),E.push(q.id)}function H(){return E.length}function P(q,x){return Z.get(q)?.get(x)}function $(q,x,A){let z=Z.get(q);if(!z)z=new Map,Z.set(q,z);z.set(x,A)}function U(q,x){let A=P(q,x);if(A)return A;let z=N(q,x),C=V.get(z);if(C)return C;let B=W.get(q);if(!B)throw Error(`Unknown dictionary "${q}". A dictionary must be created with defineDictionary() and its module must have been evaluated before it is read.`);let J=B.load(x);if(!(J instanceof Promise))return $(q,x,J),J;let O=J.then((Q)=>{return $(q,x,Q),V.delete(z),Q},(Q)=>{throw V.delete(z),Q});return V.set(z,O),O}function K(q,x){let A=N(q,x),z=P(q,x),C=I.get(A);if(C&&!(C.degraded&&z))return C;if(z)return G(A,M(z,!C));let B=U(q,x);if(!(B instanceof Promise))return G(A,M(B,!0));let J=B.then((O)=>O,(O)=>{return console.error(`Failed to load dictionary ${q} for locale ${x}; rendering keys instead.`,O),J.degraded=!0,Y});return G(A,J)}function G(q,x){return I.set(q,x),x}function M(q,x){return Object.assign(Promise.resolve(q),{status:"fulfilled",value:q,inHand:x?q:void 0})}var Y={};async function S(q,x){let A=x??X.get(q)??0,z=E.slice(A);if(z.length===0)return;let C=await Promise.all(z.map(async(B)=>{try{return await U(B,_(B,q)),!0}catch{return!1}}));if(x===void 0){let B=C.indexOf(!1),J=B===-1?z.length:B;X.set(q,Math.max(X.get(q)??0,A+J))}}function _(q,x){if(x)return x;return W.get(q)?.locales[0]??x}function L(q,x){if(!q)return;for(let[A,z]of Object.entries(q))$(A,x,z)}function R(q){if(q)j.activeLocale=q}function w(){return j.activeLocale}if(typeof window<"u"){let q=window,x=([z,C,B])=>{$(z,C,B)},A=Array.isArray(q.__GEMI_DICT__)?q.__GEMI_DICT__:[];q.__GEMI_DICT__={push:x};for(let z of A)x(z)}function F(){W.clear(),Z.clear(),V.clear(),I.clear(),X.clear(),E.length=0,j.activeLocale=null}function f(){let q=new Set,x=[],A=[];return{use(z,C,B){let J=`${z} ${C}`;if(q.has(J))return;q.add(J);let O={id:z,locale:C,strings:B};if(x.length===0){A.push(O);return}for(let Q of x)Q(O)},onUse(z){x.push(z);while(A.length>0)z(A.shift())}}}
3
- export{D as _f,H as $f,U as ag,K as bg,S as cg,L as dg,R as eg,w as fg,F as gg,f as hg};
3
+ export{D as Tf,H as Uf,U as Vf,K as Wf,S as Xf,L as Yf,R as Zf,w as _f,F as $f,f as ag};
4
4
 
5
- //# debugId=D3C5E12B52A6B18D64756E2164756E21
5
+ //# debugId=0740C19DD9D818FA64756E2164756E21
@@ -6,6 +6,6 @@
6
6
  "import type { LocaleStrings } from \"./dictionaryShape\";\n\n/**\n * Collects the dictionaries one SSR render actually read.\n *\n * Scoped per request by living in React context rather than in module state: a\n * streaming server has several renders in flight at once, so a module-level\n * collector would mix one page's dictionaries into another's payload. Context\n * is per render tree, which is exactly the boundary wanted, and it needs no\n * async-local storage to survive React's internal scheduling.\n *\n * Why stream these rather than put them in `__GEMI_DATA__`: that snapshot is\n * serialized before `renderToReadableStream` is even called, and which\n * dictionaries a page reads is only known once it has rendered. A suspended\n * segment reveals later still, long after the shell has flushed.\n *\n * The sink deliberately emits data, not markup — `streamQueryInjection` owns\n * script formatting and the `</script>`-safe encoding that goes with it.\n */\nexport interface DictionaryUse {\n id: string;\n locale: string;\n strings: LocaleStrings;\n}\n\nexport interface DictionarySink {\n /** Called during render, the first time a dictionary is read. */\n use(id: string, locale: string, strings: LocaleStrings): void;\n /** The response injector subscribes to receive uses as they happen. */\n onUse(cb: (use: DictionaryUse) => void): void;\n}\n\nexport function createDictionarySink(): DictionarySink {\n const seen = new Set<string>();\n const listeners: Array<(use: DictionaryUse) => void> = [];\n // Uses recorded before the injector subscribed — the render begins before the\n // response stream is wrapped.\n const pending: DictionaryUse[] = [];\n\n return {\n use(id, locale, strings) {\n const key = `${id} ${locale}`;\n if (seen.has(key)) return;\n seen.add(key);\n const entry: DictionaryUse = { id, locale, strings };\n if (listeners.length === 0) {\n pending.push(entry);\n return;\n }\n for (const listener of listeners) listener(entry);\n },\n onUse(cb) {\n listeners.push(cb);\n while (pending.length > 0) {\n cb(pending.shift()!);\n }\n },\n };\n}\n"
7
7
  ],
8
8
  "mappings": "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",
9
- "debugId": "D3C5E12B52A6B18D64756E2164756E21",
9
+ "debugId": "0740C19DD9D818FA64756E2164756E21",
10
10
  "names": []
11
11
  }