workerstack 0.1.0-beta.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 (605) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +21 -0
  3. package/README.md +138 -0
  4. package/dist/access.d.ts +131 -0
  5. package/dist/access.d.ts.map +1 -0
  6. package/dist/access.js +333 -0
  7. package/dist/access.js.map +1 -0
  8. package/dist/api/builder.d.ts +457 -0
  9. package/dist/api/builder.d.ts.map +1 -0
  10. package/dist/api/builder.js +45 -0
  11. package/dist/api/builder.js.map +1 -0
  12. package/dist/api/catalog.d.ts +8 -0
  13. package/dist/api/catalog.d.ts.map +1 -0
  14. package/dist/api/catalog.js +56 -0
  15. package/dist/api/catalog.js.map +1 -0
  16. package/dist/api/context.d.ts +47 -0
  17. package/dist/api/context.d.ts.map +1 -0
  18. package/dist/api/context.js +40 -0
  19. package/dist/api/context.js.map +1 -0
  20. package/dist/api/crud-router.d.ts +476 -0
  21. package/dist/api/crud-router.d.ts.map +1 -0
  22. package/dist/api/crud-router.js +354 -0
  23. package/dist/api/crud-router.js.map +1 -0
  24. package/dist/api/list-input-schema.d.ts +37 -0
  25. package/dist/api/list-input-schema.d.ts.map +1 -0
  26. package/dist/api/list-input-schema.js +63 -0
  27. package/dist/api/list-input-schema.js.map +1 -0
  28. package/dist/api/list-spec.d.ts +44 -0
  29. package/dist/api/list-spec.d.ts.map +1 -0
  30. package/dist/api/list-spec.js +49 -0
  31. package/dist/api/list-spec.js.map +1 -0
  32. package/dist/api/live-view.d.ts +14 -0
  33. package/dist/api/live-view.d.ts.map +1 -0
  34. package/dist/api/live-view.js +42 -0
  35. package/dist/api/live-view.js.map +1 -0
  36. package/dist/api/live-window.d.ts +40 -0
  37. package/dist/api/live-window.d.ts.map +1 -0
  38. package/dist/api/live-window.js +93 -0
  39. package/dist/api/live-window.js.map +1 -0
  40. package/dist/api/openapi.d.ts +6 -0
  41. package/dist/api/openapi.d.ts.map +1 -0
  42. package/dist/api/openapi.js +146 -0
  43. package/dist/api/openapi.js.map +1 -0
  44. package/dist/api/realtime-router.d.ts +94 -0
  45. package/dist/api/realtime-router.d.ts.map +1 -0
  46. package/dist/api/realtime-router.js +45 -0
  47. package/dist/api/realtime-router.js.map +1 -0
  48. package/dist/api/registry.d.ts +30 -0
  49. package/dist/api/registry.d.ts.map +1 -0
  50. package/dist/api/registry.js +236 -0
  51. package/dist/api/registry.js.map +1 -0
  52. package/dist/api/router.d.ts +15 -0
  53. package/dist/api/router.d.ts.map +1 -0
  54. package/dist/api/router.js +32 -0
  55. package/dist/api/router.js.map +1 -0
  56. package/dist/api/storage-router.d.ts +349 -0
  57. package/dist/api/storage-router.d.ts.map +1 -0
  58. package/dist/api/storage-router.js +155 -0
  59. package/dist/api/storage-router.js.map +1 -0
  60. package/dist/api/types.d.ts +55 -0
  61. package/dist/api/types.d.ts.map +1 -0
  62. package/dist/api/types.js +2 -0
  63. package/dist/api/types.js.map +1 -0
  64. package/dist/auth-password.d.ts +27 -0
  65. package/dist/auth-password.d.ts.map +1 -0
  66. package/dist/auth-password.js +60 -0
  67. package/dist/auth-password.js.map +1 -0
  68. package/dist/auth.d.ts +59 -0
  69. package/dist/auth.d.ts.map +1 -0
  70. package/dist/auth.js +146 -0
  71. package/dist/auth.js.map +1 -0
  72. package/dist/backend-internals.d.ts +35 -0
  73. package/dist/backend-internals.d.ts.map +1 -0
  74. package/dist/backend-internals.js +2 -0
  75. package/dist/backend-internals.js.map +1 -0
  76. package/dist/backend.d.ts +63 -0
  77. package/dist/backend.d.ts.map +1 -0
  78. package/dist/backend.js +59 -0
  79. package/dist/backend.js.map +1 -0
  80. package/dist/blueprint-generator.d.ts +21 -0
  81. package/dist/blueprint-generator.d.ts.map +1 -0
  82. package/dist/blueprint-generator.js +199 -0
  83. package/dist/blueprint-generator.js.map +1 -0
  84. package/dist/blueprint.d.ts +99 -0
  85. package/dist/blueprint.d.ts.map +1 -0
  86. package/dist/blueprint.js +257 -0
  87. package/dist/blueprint.js.map +1 -0
  88. package/dist/cli-skills.d.ts +16 -0
  89. package/dist/cli-skills.d.ts.map +1 -0
  90. package/dist/cli-skills.js +108 -0
  91. package/dist/cli-skills.js.map +1 -0
  92. package/dist/cli.d.ts +18 -0
  93. package/dist/cli.d.ts.map +1 -0
  94. package/dist/cli.js +205 -0
  95. package/dist/cli.js.map +1 -0
  96. package/dist/client/client.d.ts +53 -0
  97. package/dist/client/client.d.ts.map +1 -0
  98. package/dist/client/client.js +111 -0
  99. package/dist/client/client.js.map +1 -0
  100. package/dist/client/index.d.ts +4 -0
  101. package/dist/client/index.d.ts.map +1 -0
  102. package/dist/client/index.js +4 -0
  103. package/dist/client/index.js.map +1 -0
  104. package/dist/client/live-view.d.ts +49 -0
  105. package/dist/client/live-view.d.ts.map +1 -0
  106. package/dist/client/live-view.js +184 -0
  107. package/dist/client/live-view.js.map +1 -0
  108. package/dist/client/react.d.ts +4 -0
  109. package/dist/client/react.d.ts.map +1 -0
  110. package/dist/client/react.js +6 -0
  111. package/dist/client/react.js.map +1 -0
  112. package/dist/client/realtime.d.ts +54 -0
  113. package/dist/client/realtime.d.ts.map +1 -0
  114. package/dist/client/realtime.js +105 -0
  115. package/dist/client/realtime.js.map +1 -0
  116. package/dist/client/rest.d.ts +2 -0
  117. package/dist/client/rest.d.ts.map +1 -0
  118. package/dist/client/rest.js +2 -0
  119. package/dist/client/rest.js.map +1 -0
  120. package/dist/client/rpc-client.d.ts +38 -0
  121. package/dist/client/rpc-client.d.ts.map +1 -0
  122. package/dist/client/rpc-client.js +59 -0
  123. package/dist/client/rpc-client.js.map +1 -0
  124. package/dist/client/solid.d.ts +7 -0
  125. package/dist/client/solid.d.ts.map +1 -0
  126. package/dist/client/solid.js +21 -0
  127. package/dist/client/solid.js.map +1 -0
  128. package/dist/client/svelte.d.ts +6 -0
  129. package/dist/client/svelte.d.ts.map +1 -0
  130. package/dist/client/svelte.js +9 -0
  131. package/dist/client/svelte.js.map +1 -0
  132. package/dist/client/vue.d.ts +5 -0
  133. package/dist/client/vue.d.ts.map +1 -0
  134. package/dist/client/vue.js +11 -0
  135. package/dist/client/vue.js.map +1 -0
  136. package/dist/codegen.d.ts +36 -0
  137. package/dist/codegen.d.ts.map +1 -0
  138. package/dist/codegen.js +235 -0
  139. package/dist/codegen.js.map +1 -0
  140. package/dist/config.d.ts +129 -0
  141. package/dist/config.d.ts.map +1 -0
  142. package/dist/config.js +75 -0
  143. package/dist/config.js.map +1 -0
  144. package/dist/cron.d.ts +4 -0
  145. package/dist/cron.d.ts.map +1 -0
  146. package/dist/cron.js +3 -0
  147. package/dist/cron.js.map +1 -0
  148. package/dist/crud-operations.d.ts +43 -0
  149. package/dist/crud-operations.d.ts.map +1 -0
  150. package/dist/crud-operations.js +249 -0
  151. package/dist/crud-operations.js.map +1 -0
  152. package/dist/database/adapter.d.ts +26 -0
  153. package/dist/database/adapter.d.ts.map +1 -0
  154. package/dist/database/adapter.js +2 -0
  155. package/dist/database/adapter.js.map +1 -0
  156. package/dist/database/libsql.d.ts +3 -0
  157. package/dist/database/libsql.d.ts.map +1 -0
  158. package/dist/database/libsql.js +39 -0
  159. package/dist/database/libsql.js.map +1 -0
  160. package/dist/db.d.ts +15 -0
  161. package/dist/db.d.ts.map +1 -0
  162. package/dist/db.js +8 -0
  163. package/dist/db.js.map +1 -0
  164. package/dist/dev/binaries.d.ts +22 -0
  165. package/dist/dev/binaries.d.ts.map +1 -0
  166. package/dist/dev/binaries.js +119 -0
  167. package/dist/dev/binaries.js.map +1 -0
  168. package/dist/dev/env.d.ts +11 -0
  169. package/dist/dev/env.d.ts.map +1 -0
  170. package/dist/dev/env.js +71 -0
  171. package/dist/dev/env.js.map +1 -0
  172. package/dist/dev/index.d.ts +39 -0
  173. package/dist/dev/index.d.ts.map +1 -0
  174. package/dist/dev/index.js +273 -0
  175. package/dist/dev/index.js.map +1 -0
  176. package/dist/dev/processes.d.ts +37 -0
  177. package/dist/dev/processes.d.ts.map +1 -0
  178. package/dist/dev/processes.js +104 -0
  179. package/dist/dev/processes.js.map +1 -0
  180. package/dist/dev/push.d.ts +2 -0
  181. package/dist/dev/push.d.ts.map +1 -0
  182. package/dist/dev/push.js +30 -0
  183. package/dist/dev/push.js.map +1 -0
  184. package/dist/dialect.d.ts +17 -0
  185. package/dist/dialect.d.ts.map +1 -0
  186. package/dist/dialect.js +12 -0
  187. package/dist/dialect.js.map +1 -0
  188. package/dist/email/smtp.d.ts +20 -0
  189. package/dist/email/smtp.d.ts.map +1 -0
  190. package/dist/email/smtp.js +31 -0
  191. package/dist/email/smtp.js.map +1 -0
  192. package/dist/email.d.ts +26 -0
  193. package/dist/email.d.ts.map +1 -0
  194. package/dist/email.js +2 -0
  195. package/dist/email.js.map +1 -0
  196. package/dist/env-probe.d.ts +9 -0
  197. package/dist/env-probe.d.ts.map +1 -0
  198. package/dist/env-probe.js +72 -0
  199. package/dist/env-probe.js.map +1 -0
  200. package/dist/env.d.ts +62 -0
  201. package/dist/env.d.ts.map +1 -0
  202. package/dist/env.js +86 -0
  203. package/dist/env.js.map +1 -0
  204. package/dist/errors.d.ts +153 -0
  205. package/dist/errors.d.ts.map +1 -0
  206. package/dist/errors.js +106 -0
  207. package/dist/errors.js.map +1 -0
  208. package/dist/handler.d.ts +11 -0
  209. package/dist/handler.d.ts.map +1 -0
  210. package/dist/handler.js +21 -0
  211. package/dist/handler.js.map +1 -0
  212. package/dist/hosted-contract.d.ts +11 -0
  213. package/dist/hosted-contract.d.ts.map +1 -0
  214. package/dist/hosted-contract.js +50 -0
  215. package/dist/hosted-contract.js.map +1 -0
  216. package/dist/idempotency.d.ts +17 -0
  217. package/dist/idempotency.d.ts.map +1 -0
  218. package/dist/idempotency.js +65 -0
  219. package/dist/idempotency.js.map +1 -0
  220. package/dist/index.d.ts +41 -0
  221. package/dist/index.d.ts.map +1 -0
  222. package/dist/index.js +18 -0
  223. package/dist/index.js.map +1 -0
  224. package/dist/inspect.d.ts +15 -0
  225. package/dist/inspect.d.ts.map +1 -0
  226. package/dist/inspect.js +44 -0
  227. package/dist/inspect.js.map +1 -0
  228. package/dist/internal-tables.d.ts +1767 -0
  229. package/dist/internal-tables.d.ts.map +1 -0
  230. package/dist/internal-tables.js +114 -0
  231. package/dist/internal-tables.js.map +1 -0
  232. package/dist/jobs/cron.d.ts +15 -0
  233. package/dist/jobs/cron.d.ts.map +1 -0
  234. package/dist/jobs/cron.js +74 -0
  235. package/dist/jobs/cron.js.map +1 -0
  236. package/dist/jobs/define.d.ts +186 -0
  237. package/dist/jobs/define.d.ts.map +1 -0
  238. package/dist/jobs/define.js +99 -0
  239. package/dist/jobs/define.js.map +1 -0
  240. package/dist/jobs/index.d.ts +9 -0
  241. package/dist/jobs/index.d.ts.map +1 -0
  242. package/dist/jobs/index.js +7 -0
  243. package/dist/jobs/index.js.map +1 -0
  244. package/dist/jobs/queue.d.ts +13 -0
  245. package/dist/jobs/queue.d.ts.map +1 -0
  246. package/dist/jobs/queue.js +71 -0
  247. package/dist/jobs/queue.js.map +1 -0
  248. package/dist/jobs/slots.d.ts +30 -0
  249. package/dist/jobs/slots.d.ts.map +1 -0
  250. package/dist/jobs/slots.js +53 -0
  251. package/dist/jobs/slots.js.map +1 -0
  252. package/dist/jobs/worker.d.ts +45 -0
  253. package/dist/jobs/worker.d.ts.map +1 -0
  254. package/dist/jobs/worker.js +605 -0
  255. package/dist/jobs/worker.js.map +1 -0
  256. package/dist/lifecycle.d.ts +10 -0
  257. package/dist/lifecycle.d.ts.map +1 -0
  258. package/dist/lifecycle.js +37 -0
  259. package/dist/lifecycle.js.map +1 -0
  260. package/dist/list-query.d.ts +62 -0
  261. package/dist/list-query.d.ts.map +1 -0
  262. package/dist/list-query.js +190 -0
  263. package/dist/list-query.js.map +1 -0
  264. package/dist/live/apply.d.ts +13 -0
  265. package/dist/live/apply.d.ts.map +1 -0
  266. package/dist/live/apply.js +32 -0
  267. package/dist/live/apply.js.map +1 -0
  268. package/dist/live/index.d.ts +48 -0
  269. package/dist/live/index.d.ts.map +1 -0
  270. package/dist/live/index.js +108 -0
  271. package/dist/live/index.js.map +1 -0
  272. package/dist/live/protocol.d.ts +47 -0
  273. package/dist/live/protocol.d.ts.map +1 -0
  274. package/dist/live/protocol.js +12 -0
  275. package/dist/live/protocol.js.map +1 -0
  276. package/dist/live/sse.d.ts +22 -0
  277. package/dist/live/sse.d.ts.map +1 -0
  278. package/dist/live/sse.js +41 -0
  279. package/dist/live/sse.js.map +1 -0
  280. package/dist/logging.d.ts +8 -0
  281. package/dist/logging.d.ts.map +1 -0
  282. package/dist/logging.js +6 -0
  283. package/dist/logging.js.map +1 -0
  284. package/dist/manifest-diff.d.ts +6 -0
  285. package/dist/manifest-diff.d.ts.map +1 -0
  286. package/dist/manifest-diff.js +42 -0
  287. package/dist/manifest-diff.js.map +1 -0
  288. package/dist/manifest.d.ts +87 -0
  289. package/dist/manifest.d.ts.map +1 -0
  290. package/dist/manifest.js +237 -0
  291. package/dist/manifest.js.map +1 -0
  292. package/dist/messaging/email.d.ts +16 -0
  293. package/dist/messaging/email.d.ts.map +1 -0
  294. package/dist/messaging/email.js +8 -0
  295. package/dist/messaging/email.js.map +1 -0
  296. package/dist/messaging/index.d.ts +8 -0
  297. package/dist/messaging/index.d.ts.map +1 -0
  298. package/dist/messaging/index.js +4 -0
  299. package/dist/messaging/index.js.map +1 -0
  300. package/dist/messaging/journal.d.ts +4 -0
  301. package/dist/messaging/journal.d.ts.map +1 -0
  302. package/dist/messaging/journal.js +19 -0
  303. package/dist/messaging/journal.js.map +1 -0
  304. package/dist/messaging/runtime.d.ts +16 -0
  305. package/dist/messaging/runtime.d.ts.map +1 -0
  306. package/dist/messaging/runtime.js +213 -0
  307. package/dist/messaging/runtime.js.map +1 -0
  308. package/dist/messaging/standalone.d.ts +27 -0
  309. package/dist/messaging/standalone.d.ts.map +1 -0
  310. package/dist/messaging/standalone.js +18 -0
  311. package/dist/messaging/standalone.js.map +1 -0
  312. package/dist/messaging/telegram.d.ts +16 -0
  313. package/dist/messaging/telegram.d.ts.map +1 -0
  314. package/dist/messaging/telegram.js +5 -0
  315. package/dist/messaging/telegram.js.map +1 -0
  316. package/dist/messaging/types.d.ts +22 -0
  317. package/dist/messaging/types.d.ts.map +1 -0
  318. package/dist/messaging/types.js +17 -0
  319. package/dist/messaging/types.js.map +1 -0
  320. package/dist/platform.d.ts +25 -0
  321. package/dist/platform.d.ts.map +1 -0
  322. package/dist/platform.js +24 -0
  323. package/dist/platform.js.map +1 -0
  324. package/dist/provision-internals.d.ts +23 -0
  325. package/dist/provision-internals.d.ts.map +1 -0
  326. package/dist/provision-internals.js +7 -0
  327. package/dist/provision-internals.js.map +1 -0
  328. package/dist/provision-runtime.d.ts +6 -0
  329. package/dist/provision-runtime.d.ts.map +1 -0
  330. package/dist/provision-runtime.js +41 -0
  331. package/dist/provision-runtime.js.map +1 -0
  332. package/dist/provision-schema.d.ts +16 -0
  333. package/dist/provision-schema.d.ts.map +1 -0
  334. package/dist/provision-schema.js +59 -0
  335. package/dist/provision-schema.js.map +1 -0
  336. package/dist/provision.d.ts +8 -0
  337. package/dist/provision.d.ts.map +1 -0
  338. package/dist/provision.js +16 -0
  339. package/dist/provision.js.map +1 -0
  340. package/dist/query/api.d.ts +10 -0
  341. package/dist/query/api.d.ts.map +1 -0
  342. package/dist/query/api.js +7 -0
  343. package/dist/query/api.js.map +1 -0
  344. package/dist/query/client.d.ts +28 -0
  345. package/dist/query/client.d.ts.map +1 -0
  346. package/dist/query/client.js +87 -0
  347. package/dist/query/client.js.map +1 -0
  348. package/dist/query/fetch.d.ts +3 -0
  349. package/dist/query/fetch.d.ts.map +1 -0
  350. package/dist/query/fetch.js +4 -0
  351. package/dist/query/fetch.js.map +1 -0
  352. package/dist/query/index.d.ts +8 -0
  353. package/dist/query/index.d.ts.map +1 -0
  354. package/dist/query/index.js +4 -0
  355. package/dist/query/index.js.map +1 -0
  356. package/dist/query/infer.d.ts +25 -0
  357. package/dist/query/infer.d.ts.map +1 -0
  358. package/dist/query/infer.js +2 -0
  359. package/dist/query/infer.js.map +1 -0
  360. package/dist/query/react.d.ts +3 -0
  361. package/dist/query/react.d.ts.map +1 -0
  362. package/dist/query/react.js +2 -0
  363. package/dist/query/react.js.map +1 -0
  364. package/dist/query/realtime-flush.d.ts +26 -0
  365. package/dist/query/realtime-flush.d.ts.map +1 -0
  366. package/dist/query/realtime-flush.js +45 -0
  367. package/dist/query/realtime-flush.js.map +1 -0
  368. package/dist/query/realtime-stream.d.ts +3 -0
  369. package/dist/query/realtime-stream.d.ts.map +1 -0
  370. package/dist/query/realtime-stream.js +3 -0
  371. package/dist/query/realtime-stream.js.map +1 -0
  372. package/dist/query/realtime.d.ts +88 -0
  373. package/dist/query/realtime.d.ts.map +1 -0
  374. package/dist/query/realtime.js +255 -0
  375. package/dist/query/realtime.js.map +1 -0
  376. package/dist/rate-limit.d.ts +8 -0
  377. package/dist/rate-limit.d.ts.map +1 -0
  378. package/dist/rate-limit.js +46 -0
  379. package/dist/rate-limit.js.map +1 -0
  380. package/dist/readiness-probes.d.ts +4 -0
  381. package/dist/readiness-probes.d.ts.map +1 -0
  382. package/dist/readiness-probes.js +23 -0
  383. package/dist/readiness-probes.js.map +1 -0
  384. package/dist/readiness.d.ts +39 -0
  385. package/dist/readiness.d.ts.map +1 -0
  386. package/dist/readiness.js +72 -0
  387. package/dist/readiness.js.map +1 -0
  388. package/dist/realtime/facade.d.ts +20 -0
  389. package/dist/realtime/facade.d.ts.map +1 -0
  390. package/dist/realtime/facade.js +37 -0
  391. package/dist/realtime/facade.js.map +1 -0
  392. package/dist/realtime/filter.d.ts +42 -0
  393. package/dist/realtime/filter.d.ts.map +1 -0
  394. package/dist/realtime/filter.js +86 -0
  395. package/dist/realtime/filter.js.map +1 -0
  396. package/dist/realtime/heartbeat.d.ts +20 -0
  397. package/dist/realtime/heartbeat.d.ts.map +1 -0
  398. package/dist/realtime/heartbeat.js +64 -0
  399. package/dist/realtime/heartbeat.js.map +1 -0
  400. package/dist/realtime/publisher.d.ts +19 -0
  401. package/dist/realtime/publisher.d.ts.map +1 -0
  402. package/dist/realtime/publisher.js +8 -0
  403. package/dist/realtime/publisher.js.map +1 -0
  404. package/dist/runtime.d.ts +141 -0
  405. package/dist/runtime.d.ts.map +1 -0
  406. package/dist/runtime.js +463 -0
  407. package/dist/runtime.js.map +1 -0
  408. package/dist/schema-export.d.ts +2 -0
  409. package/dist/schema-export.d.ts.map +1 -0
  410. package/dist/schema-export.js +2 -0
  411. package/dist/schema-export.js.map +1 -0
  412. package/dist/scope.d.ts +4 -0
  413. package/dist/scope.d.ts.map +1 -0
  414. package/dist/scope.js +13 -0
  415. package/dist/scope.js.map +1 -0
  416. package/dist/standard-schema.d.ts +13 -0
  417. package/dist/standard-schema.d.ts.map +1 -0
  418. package/dist/standard-schema.js +34 -0
  419. package/dist/standard-schema.js.map +1 -0
  420. package/dist/start/auth-client.d.ts +11 -0
  421. package/dist/start/auth-client.d.ts.map +1 -0
  422. package/dist/start/auth-client.js +15 -0
  423. package/dist/start/auth-client.js.map +1 -0
  424. package/dist/start/create-start-worker.d.ts +16 -0
  425. package/dist/start/create-start-worker.d.ts.map +1 -0
  426. package/dist/start/create-start-worker.js +24 -0
  427. package/dist/start/create-start-worker.js.map +1 -0
  428. package/dist/start/index.d.ts +66 -0
  429. package/dist/start/index.d.ts.map +1 -0
  430. package/dist/start/index.js +49 -0
  431. package/dist/start/index.js.map +1 -0
  432. package/dist/start/isomorphic-fetch.d.ts +22 -0
  433. package/dist/start/isomorphic-fetch.d.ts.map +1 -0
  434. package/dist/start/isomorphic-fetch.js +49 -0
  435. package/dist/start/isomorphic-fetch.js.map +1 -0
  436. package/dist/start/server-entry.d.ts +7 -0
  437. package/dist/start/server-entry.d.ts.map +1 -0
  438. package/dist/start/server-entry.js +8 -0
  439. package/dist/start/server-entry.js.map +1 -0
  440. package/dist/storage/background.d.ts +3 -0
  441. package/dist/storage/background.d.ts.map +1 -0
  442. package/dist/storage/background.js +3 -0
  443. package/dist/storage/background.js.map +1 -0
  444. package/dist/storage/buckets.d.ts +78 -0
  445. package/dist/storage/buckets.d.ts.map +1 -0
  446. package/dist/storage/buckets.js +177 -0
  447. package/dist/storage/buckets.js.map +1 -0
  448. package/dist/storage/delete.d.ts +8 -0
  449. package/dist/storage/delete.d.ts.map +1 -0
  450. package/dist/storage/delete.js +10 -0
  451. package/dist/storage/delete.js.map +1 -0
  452. package/dist/storage/file-meta.d.ts +37 -0
  453. package/dist/storage/file-meta.d.ts.map +1 -0
  454. package/dist/storage/file-meta.js +166 -0
  455. package/dist/storage/file-meta.js.map +1 -0
  456. package/dist/storage/index.d.ts +28 -0
  457. package/dist/storage/index.d.ts.map +1 -0
  458. package/dist/storage/index.js +5 -0
  459. package/dist/storage/index.js.map +1 -0
  460. package/dist/storage/local.d.ts +15 -0
  461. package/dist/storage/local.d.ts.map +1 -0
  462. package/dist/storage/local.js +56 -0
  463. package/dist/storage/local.js.map +1 -0
  464. package/dist/storage/operations.d.ts +54 -0
  465. package/dist/storage/operations.d.ts.map +1 -0
  466. package/dist/storage/operations.js +212 -0
  467. package/dist/storage/operations.js.map +1 -0
  468. package/dist/storage/registry.d.ts +11 -0
  469. package/dist/storage/registry.d.ts.map +1 -0
  470. package/dist/storage/registry.js +23 -0
  471. package/dist/storage/registry.js.map +1 -0
  472. package/dist/storage/s3.d.ts +35 -0
  473. package/dist/storage/s3.d.ts.map +1 -0
  474. package/dist/storage/s3.js +125 -0
  475. package/dist/storage/s3.js.map +1 -0
  476. package/dist/storage/sigv4.d.ts +24 -0
  477. package/dist/storage/sigv4.d.ts.map +1 -0
  478. package/dist/storage/sigv4.js +107 -0
  479. package/dist/storage/sigv4.js.map +1 -0
  480. package/dist/storage/sweep.d.ts +9 -0
  481. package/dist/storage/sweep.d.ts.map +1 -0
  482. package/dist/storage/sweep.js +17 -0
  483. package/dist/storage/sweep.js.map +1 -0
  484. package/dist/sync/collection.d.ts +106 -0
  485. package/dist/sync/collection.d.ts.map +1 -0
  486. package/dist/sync/collection.js +258 -0
  487. package/dist/sync/collection.js.map +1 -0
  488. package/dist/sync/index.d.ts +8 -0
  489. package/dist/sync/index.d.ts.map +1 -0
  490. package/dist/sync/index.js +4 -0
  491. package/dist/sync/index.js.map +1 -0
  492. package/dist/sync/realtime-sync.d.ts +31 -0
  493. package/dist/sync/realtime-sync.d.ts.map +1 -0
  494. package/dist/sync/realtime-sync.js +46 -0
  495. package/dist/sync/realtime-sync.js.map +1 -0
  496. package/dist/sync/sync-client.d.ts +28 -0
  497. package/dist/sync/sync-client.d.ts.map +1 -0
  498. package/dist/sync/sync-client.js +52 -0
  499. package/dist/sync/sync-client.js.map +1 -0
  500. package/dist/sync/update-queue.d.ts +27 -0
  501. package/dist/sync/update-queue.d.ts.map +1 -0
  502. package/dist/sync/update-queue.js +66 -0
  503. package/dist/sync/update-queue.js.map +1 -0
  504. package/dist/testing/auth.d.ts +85 -0
  505. package/dist/testing/auth.d.ts.map +1 -0
  506. package/dist/testing/auth.js +140 -0
  507. package/dist/testing/auth.js.map +1 -0
  508. package/dist/testing/client.d.ts +6 -0
  509. package/dist/testing/client.d.ts.map +1 -0
  510. package/dist/testing/client.js +9 -0
  511. package/dist/testing/client.js.map +1 -0
  512. package/dist/testing/database.d.ts +6 -0
  513. package/dist/testing/database.d.ts.map +1 -0
  514. package/dist/testing/database.js +8 -0
  515. package/dist/testing/database.js.map +1 -0
  516. package/dist/testing/email.d.ts +15 -0
  517. package/dist/testing/email.d.ts.map +1 -0
  518. package/dist/testing/email.js +32 -0
  519. package/dist/testing/email.js.map +1 -0
  520. package/dist/testing/fixture.d.ts +51 -0
  521. package/dist/testing/fixture.d.ts.map +1 -0
  522. package/dist/testing/fixture.js +177 -0
  523. package/dist/testing/fixture.js.map +1 -0
  524. package/dist/testing/jobs.d.ts +40 -0
  525. package/dist/testing/jobs.d.ts.map +1 -0
  526. package/dist/testing/jobs.js +76 -0
  527. package/dist/testing/jobs.js.map +1 -0
  528. package/dist/testing/logs.d.ts +18 -0
  529. package/dist/testing/logs.d.ts.map +1 -0
  530. package/dist/testing/logs.js +53 -0
  531. package/dist/testing/logs.js.map +1 -0
  532. package/dist/testing/messaging.d.ts +21 -0
  533. package/dist/testing/messaging.d.ts.map +1 -0
  534. package/dist/testing/messaging.js +34 -0
  535. package/dist/testing/messaging.js.map +1 -0
  536. package/dist/testing/storage.d.ts +7 -0
  537. package/dist/testing/storage.d.ts.map +1 -0
  538. package/dist/testing/storage.js +29 -0
  539. package/dist/testing/storage.js.map +1 -0
  540. package/dist/testing/workers-fakes.d.ts +17 -0
  541. package/dist/testing/workers-fakes.d.ts.map +1 -0
  542. package/dist/testing/workers-fakes.js +98 -0
  543. package/dist/testing/workers-fakes.js.map +1 -0
  544. package/dist/testing.d.ts +12 -0
  545. package/dist/testing.d.ts.map +1 -0
  546. package/dist/testing.js +5 -0
  547. package/dist/testing.js.map +1 -0
  548. package/dist/typeid.d.ts +46 -0
  549. package/dist/typeid.d.ts.map +1 -0
  550. package/dist/typeid.js +130 -0
  551. package/dist/typeid.js.map +1 -0
  552. package/dist/vite.d.ts +26 -0
  553. package/dist/vite.d.ts.map +1 -0
  554. package/dist/vite.js +100 -0
  555. package/dist/vite.js.map +1 -0
  556. package/dist/worker-plan.d.ts +37 -0
  557. package/dist/worker-plan.d.ts.map +1 -0
  558. package/dist/worker-plan.js +63 -0
  559. package/dist/worker-plan.js.map +1 -0
  560. package/dist/workers/app.d.ts +19 -0
  561. package/dist/workers/app.d.ts.map +1 -0
  562. package/dist/workers/app.js +56 -0
  563. package/dist/workers/app.js.map +1 -0
  564. package/dist/workers/entry.d.ts +7 -0
  565. package/dist/workers/entry.d.ts.map +1 -0
  566. package/dist/workers/entry.js +8 -0
  567. package/dist/workers/entry.js.map +1 -0
  568. package/dist/workers/index.d.ts +23 -0
  569. package/dist/workers/index.d.ts.map +1 -0
  570. package/dist/workers/index.js +39 -0
  571. package/dist/workers/index.js.map +1 -0
  572. package/dist/workers/r2.d.ts +24 -0
  573. package/dist/workers/r2.d.ts.map +1 -0
  574. package/dist/workers/r2.js +76 -0
  575. package/dist/workers/r2.js.map +1 -0
  576. package/dist/workers/rate-limiter.d.ts +9 -0
  577. package/dist/workers/rate-limiter.d.ts.map +1 -0
  578. package/dist/workers/rate-limiter.js +22 -0
  579. package/dist/workers/rate-limiter.js.map +1 -0
  580. package/dist/workers/realtime-hub.d.ts +20 -0
  581. package/dist/workers/realtime-hub.d.ts.map +1 -0
  582. package/dist/workers/realtime-hub.js +117 -0
  583. package/dist/workers/realtime-hub.js.map +1 -0
  584. package/dist/workers/registry.d.ts +13 -0
  585. package/dist/workers/registry.d.ts.map +1 -0
  586. package/dist/workers/registry.js +19 -0
  587. package/dist/workers/registry.js.map +1 -0
  588. package/dist/workers/scheduler.d.ts +13 -0
  589. package/dist/workers/scheduler.d.ts.map +1 -0
  590. package/dist/workers/scheduler.js +71 -0
  591. package/dist/workers/scheduler.js.map +1 -0
  592. package/dist/workers/types.d.ts +55 -0
  593. package/dist/workers/types.d.ts.map +1 -0
  594. package/dist/workers/types.js +4 -0
  595. package/dist/workers/types.js.map +1 -0
  596. package/dist/workers/wrangler.d.ts +62 -0
  597. package/dist/workers/wrangler.d.ts.map +1 -0
  598. package/dist/workers/wrangler.js +90 -0
  599. package/dist/workers/wrangler.js.map +1 -0
  600. package/package.json +286 -0
  601. package/skills/creating-workerstack-apps/SKILL.md +45 -0
  602. package/skills/creating-workerstack-apps/agents/openai.yaml +4 -0
  603. package/skills/creating-workerstack-apps/references/application-structure.md +219 -0
  604. package/skills/creating-workerstack-apps/references/runtime-integrations.md +96 -0
  605. package/skills/creating-workerstack-apps/references/verification.md +29 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/jobs/worker.ts"],"names":[],"mappings":"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","sourcesContent":["// src/jobs/worker.ts — the queue worker. One `tick()` is a full cycle:\n// recover expired leases → reap old succeeded rows → claim and run queue jobs.\nimport { and, desc, eq, inArray, isNotNull, lt, lte, sql } from 'drizzle-orm'\n\nimport type { AnyDb } from '../dialect'\nimport type { WorkerstackLogger } from '../logging'\nimport type {\n AnyBackgroundDefinition,\n JobsDefs,\n JobsRuntimeFacade,\n TickResult,\n} from './define'\n\nimport { workerstackJobs } from '../internal-tables'\nimport { consoleLogger } from '../logging'\nimport { validateStandardSchema } from '../standard-schema'\nimport { parseCron } from './cron'\nimport { backoffMs, DEFAULT_RETRIES, leaseDurationFor } from './define'\nimport { enqueueJob } from './queue'\nimport {\n CRON_PREFIX,\n floorSlot,\n nextCronSlot,\n slotsDue,\n SLOT_MS,\n} from './slots'\n\nconst CLAIM_BATCH = 10\nconst SUCCEEDED_RETENTION_MS = 24 * 60 * 60 * 1000\nconst REAP_INTERVAL_MS = 60 * 60_000\n\nclass JobExecutionTimeoutError extends Error {\n constructor(maxRuntime: number) {\n super(`execution timed out after ${maxRuntime}ms`)\n this.name = 'JobExecutionTimeoutError'\n }\n}\n\nclass JobLeaseLostError extends Error {\n constructor() {\n super('job lease ownership was lost')\n this.name = 'JobLeaseLostError'\n }\n}\n\ntype JobRow = {\n id: string\n type: string\n payloadJson: string\n attempts: number\n runAt: number\n}\n\ntype LeaseOwner = {\n attempt: number\n lockedUntil: number\n}\n\ntype ClaimedWork = {\n row: JobRow\n def: AnyBackgroundDefinition\n owner: LeaseOwner\n}\n\ntype LeaseHeartbeat = {\n owner: LeaseOwner\n lost: Promise<void>\n stop(): Promise<void>\n}\n\ntype PumpResult = { wake?: Promise<void> }\n\ntype CronCursor = {\n checkedThrough: number\n}\n\nfunction jobEvent(\n event: string,\n row: JobRow,\n fields: Record<string, unknown> = {},\n) {\n return {\n source: 'workerstack.jobs',\n event,\n jobId: row.id,\n jobType: row.type,\n attempt: Number(row.attempts),\n ...fields,\n }\n}\n\nfunction capacityFor(def: AnyBackgroundDefinition): number {\n return def.kind === 'job' && def.concurrency !== undefined\n ? def.concurrency\n : CLAIM_BATCH\n}\n\nfunction toError(err: unknown): Error {\n return err instanceof Error ? err : new Error(String(err))\n}\n\nfunction maxAttempts(def: AnyBackgroundDefinition): number {\n return 1 + (def.retries ?? DEFAULT_RETRIES)\n}\n\n/** Resolve a stored row type back to its definition. Cron rows carry the\n * reserved prefix; queue rows use the definition key verbatim. */\nfunction definitionFor(\n defs: JobsDefs,\n type: string,\n): AnyBackgroundDefinition | undefined {\n if (type.startsWith(CRON_PREFIX)) {\n const def = defs[type.slice(CRON_PREFIX.length)]\n return def?.kind === 'cron' ? def : undefined\n }\n const def = defs[type]\n return def?.kind === 'job' ? def : undefined\n}\n\n/** Queue jobs release terminal dedupe keys; cron slots retain durable ownership. */\nfunction terminalPatch(def: AnyBackgroundDefinition) {\n return def.kind === 'cron' ? {} : { dedupeKey: null }\n}\n\n/** `dedupeUntil: 'start'` releases the key at claim; everything else keeps it\n * until a terminal state, so the claim patch stays unchanged for them. */\nfunction claimPatch(def: AnyBackgroundDefinition) {\n return def.kind === 'job' && def.dedupeUntil === 'start'\n ? { dedupeKey: null }\n : {}\n}\n\nexport function createJobRunner(deps: {\n db: AnyDb\n defs: JobsDefs\n /** Handler ctx WITHOUT `jobs`; the facade is injected via setJobsFacade. */\n ctx: Record<string, unknown>\n logger?: WorkerstackLogger\n}) {\n const { db, defs } = deps\n const logger = deps.logger ?? consoleLogger\n const t = workerstackJobs\n const ctx = { ...deps.ctx } as Record<string, unknown>\n let lastReapAt = 0\n const active = new Map<string, Set<Promise<void>>>()\n const cronCursors = new Map<string, CronCursor>()\n\n function ownershipPredicate(id: string, owner: LeaseOwner) {\n return and(\n eq(t.id, id),\n eq(t.status, 'running'),\n eq(t.attempts, owner.attempt),\n eq(t.lockedUntil, owner.lockedUntil),\n )\n }\n\n function startLeaseHeartbeat(args: {\n row: JobRow\n def: AnyBackgroundDefinition\n owner: LeaseOwner\n onLost: () => void\n }): LeaseHeartbeat {\n const owner = args.owner\n const intervalMs = Math.max(10, Math.floor(leaseDurationFor(args.def) / 3))\n let stopped = false\n let resolveLost!: () => void\n const lost = new Promise<void>((resolve) => {\n resolveLost = resolve\n })\n let chain = Promise.resolve()\n const lose = () => {\n if (stopped) return\n stopped = true\n clearInterval(timer)\n resolveLost()\n args.onLost()\n }\n const renew = () => {\n chain = chain\n .then(async () => {\n if (stopped) return\n const nextLockedUntil = Date.now() + leaseDurationFor(args.def)\n const updated = await db\n .update(t)\n .set({ lockedUntil: nextLockedUntil })\n .where(ownershipPredicate(args.row.id, owner))\n .returning({ id: t.id })\n if (!updated[0]) return lose()\n owner.lockedUntil = nextLockedUntil\n })\n .catch(() => lose())\n }\n const timer = setInterval(renew, intervalMs)\n return {\n owner,\n lost,\n async stop() {\n stopped = true\n clearInterval(timer)\n await chain\n },\n }\n }\n\n /** Cron rows carry no payload — their handler input is the slot itself. */\n function resolveInput(def: AnyBackgroundDefinition, row: JobRow): unknown {\n if (def.kind === 'cron') {\n return { scheduledFor: new Date(Number(row.runAt)) }\n }\n const raw = JSON.parse(row.payloadJson)\n return def.input\n ? validateStandardSchema(def.input, raw, 'job payload')\n : undefined\n }\n\n /** Hydrate each cron cursor once, then advance it in this worker's memory. */\n async function cronCursor(type: string, now: number): Promise<CronCursor> {\n const cached = cronCursors.get(type)\n if (cached) return cached\n\n const rows = await db\n .select({ runAt: t.runAt })\n .from(t)\n .where(eq(t.type, type))\n .orderBy(desc(t.runAt))\n .limit(1)\n const cursor = {\n checkedThrough:\n rows[0]?.runAt == null\n ? floorSlot(now) - SLOT_MS\n : Number(rows[0].runAt),\n }\n cronCursors.set(type, cursor)\n return cursor\n }\n\n /** Enqueue a row per due slot. The unique(type, dedupeKey) constraint makes\n * this safe to run concurrently in any number of processes. */\n async function materializeCronSlots(now: number) {\n const through = floorSlot(now)\n for (const [name, def] of Object.entries(defs)) {\n if (def.kind !== 'cron') continue\n const type = `${CRON_PREFIX}${name}`\n const cursor = await cronCursor(type, now)\n const slots = slotsDue({\n cron: parseCron(def.schedule),\n from: cursor.checkedThrough,\n to: through,\n catchUp: def.catchUp,\n catchUpWindowMs: def.catchUpWindow,\n })\n for (const slot of slots) {\n await enqueueJob(db, defs, name, null, {\n runAt: slot,\n dedupeKey: String(slot),\n })\n cursor.checkedThrough = slot\n }\n cursor.checkedThrough = Math.max(cursor.checkedThrough, through)\n }\n }\n\n async function fireOnFailed(\n def: AnyBackgroundDefinition,\n input: unknown,\n error: Error,\n ) {\n if (!def.onFailed) return\n try {\n await (def.onFailed as (i: unknown, e: Error, c: unknown) => unknown)(\n input,\n error,\n ctx,\n )\n } catch (hookErr) {\n logger.error('[workerstack] onFailed hook threw:', hookErr)\n }\n }\n\n /** running rows whose lease expired → pending (or failed when exhausted). */\n async function recoverExpiredLeases(now: number) {\n const expired: (JobRow & {\n lastError: string | null\n lockedUntil: number\n })[] = await db\n .select({\n id: t.id,\n type: t.type,\n payloadJson: t.payloadJson,\n attempts: t.attempts,\n lastError: t.lastError,\n runAt: t.runAt,\n lockedUntil: t.lockedUntil,\n })\n .from(t)\n .where(\n and(\n eq(t.status, 'running'),\n isNotNull(t.lockedUntil),\n lt(t.lockedUntil, now),\n ),\n )\n for (const row of expired) {\n const owner = {\n attempt: Number(row.attempts),\n lockedUntil: Number(row.lockedUntil),\n }\n const def = definitionFor(defs, row.type)\n const error = new Error('lease expired (worker crashed or timed out)')\n if (!def) {\n await db\n .update(t)\n .set({\n status: 'failed',\n finishedAt: now,\n lockedUntil: null,\n lastError: `unknown job type \"${row.type}\"`,\n dedupeKey: null,\n })\n .where(ownershipPredicate(row.id, owner))\n continue\n }\n if (Number(row.attempts) >= maxAttempts(def)) {\n const updated = await db\n .update(t)\n .set({\n status: 'failed',\n finishedAt: now,\n lockedUntil: null,\n lastError: error.message,\n ...terminalPatch(def),\n })\n .where(ownershipPredicate(row.id, owner))\n .returning({ id: t.id })\n if (updated[0]) await fireOnFailed(def, resolveInput(def, row), error)\n } else {\n await db\n .update(t)\n .set({\n status: 'pending',\n lockedUntil: null,\n runAt: now + backoffMs(def, Number(row.attempts)),\n lastError: error.message,\n })\n .where(ownershipPredicate(row.id, owner))\n }\n }\n }\n\n async function reapSucceeded(now: number) {\n await db\n .delete(t)\n .where(\n and(\n eq(t.status, 'succeeded'),\n lt(t.finishedAt, now - SUCCEEDED_RETENTION_MS),\n ),\n )\n }\n\n /** Atomically claim up to `limit` runnable jobs of one type. */\n async function claim(\n type: string,\n def: AnyBackgroundDefinition,\n limit: number,\n now: number,\n leaseUntil: number,\n ): Promise<JobRow[]> {\n const pendingIds = db\n .select({ id: t.id })\n .from(t)\n .where(and(eq(t.type, type), eq(t.status, 'pending'), lte(t.runAt, now)))\n .orderBy(t.runAt)\n .limit(limit)\n // SQLite's single-writer model makes the one-statement UPDATE atomic.\n const sub = pendingIds\n const rows: JobRow[] = await db\n .update(t)\n .set({\n status: 'running',\n lockedUntil: leaseUntil,\n attempts: sql`${t.attempts} + 1`,\n ...claimPatch(def),\n })\n .where(and(inArray(t.id, sub), eq(t.status, 'pending')))\n .returning({\n id: t.id,\n type: t.type,\n payloadJson: t.payloadJson,\n attempts: t.attempts,\n runAt: t.runAt,\n })\n return rows\n }\n\n async function claimAvailable(\n type: string,\n def: AnyBackgroundDefinition,\n now: number,\n ): Promise<ClaimedWork[]> {\n const runningRows = await db\n .select({ id: t.id })\n .from(t)\n .where(and(eq(t.type, type), eq(t.status, 'running')))\n let available = capacityFor(def) - runningRows.length\n if (available <= 0) return []\n\n const leaseUntil = now + leaseDurationFor(def)\n const work: ClaimedWork[] = []\n while (available > 0) {\n const limit = Math.min(CLAIM_BATCH, available)\n const rows = await claim(type, def, limit, now, leaseUntil)\n for (const row of rows) {\n work.push({\n row,\n def,\n owner: { attempt: Number(row.attempts), lockedUntil: leaseUntil },\n })\n }\n available -= rows.length\n if (rows.length < limit) break\n }\n return work\n }\n\n // `now` is the tick's injected clock: retry runAt math uses it so tests can\n // drive backoff deterministically. finishedAt uses the real clock (a handler\n // may run long past the tick's start).\n async function runJob(\n row: JobRow,\n def: AnyBackgroundDefinition,\n now: number,\n owner: LeaseOwner,\n ): Promise<'ran' | 'failed' | 'lost'> {\n const startedAt = Date.now()\n let input: unknown\n try {\n input = resolveInput(def, row)\n } catch (err) {\n // Stored payload no longer parses (schema drift): retrying can't help.\n const e = toError(err)\n const updated = await db\n .update(t)\n .set({\n status: 'failed',\n finishedAt: Date.now(),\n lockedUntil: null,\n lastError: e.message,\n ...terminalPatch(def),\n })\n .where(ownershipPredicate(row.id, owner))\n .returning({ id: t.id })\n if (!updated[0]) return 'lost'\n await fireOnFailed(def, undefined, e)\n return 'failed'\n }\n const controller = new AbortController()\n const handlerCtx = { ...ctx, signal: controller.signal }\n logger.info(JSON.stringify(jobEvent('job.claimed', row)))\n let lost = false\n const heartbeat = startLeaseHeartbeat({\n row,\n def,\n owner,\n onLost: () => {\n lost = true\n controller.abort(new JobLeaseLostError())\n logger.warn(\n JSON.stringify(\n jobEvent('job.lease_lost', row, {\n durationMs: Date.now() - startedAt,\n }),\n ),\n )\n },\n })\n const deadline =\n def.maxRuntime === undefined\n ? undefined\n : setTimeout(() => {\n controller.abort(new JobExecutionTimeoutError(def.maxRuntime!))\n logger.warn(\n JSON.stringify(\n jobEvent('job.execution_timed_out', row, {\n durationMs: Date.now() - startedAt,\n }),\n ),\n )\n }, def.maxRuntime)\n try {\n await (def.handler as (i: unknown, c: unknown) => unknown)(\n input,\n handlerCtx,\n )\n if (controller.signal.reason instanceof JobExecutionTimeoutError) {\n throw controller.signal.reason\n }\n if (deadline) clearTimeout(deadline)\n await heartbeat.stop()\n if (lost) return 'lost'\n const updated = await db\n .update(t)\n .set({\n status: 'succeeded',\n finishedAt: Date.now(),\n lockedUntil: null,\n ...terminalPatch(def),\n })\n .where(ownershipPredicate(row.id, owner))\n .returning({ id: t.id })\n if (!updated[0]) return 'lost'\n logger.info(\n JSON.stringify(\n jobEvent('job.completed', row, {\n durationMs: Date.now() - startedAt,\n }),\n ),\n )\n return 'ran'\n } catch (err) {\n if (deadline) clearTimeout(deadline)\n const e =\n controller.signal.reason instanceof JobExecutionTimeoutError\n ? controller.signal.reason\n : toError(err)\n await heartbeat.stop()\n if (lost) return 'lost'\n if (Number(row.attempts) < maxAttempts(def)) {\n const updated = await db\n .update(t)\n .set({\n status: 'pending',\n lockedUntil: null,\n runAt: now + backoffMs(def, Number(row.attempts)),\n lastError: e.message,\n })\n .where(ownershipPredicate(row.id, owner))\n .returning({ id: t.id })\n if (!updated[0]) return 'lost'\n logger.warn(\n JSON.stringify(\n jobEvent('job.retrying', row, {\n durationMs: Date.now() - startedAt,\n error: e.message,\n }),\n ),\n )\n } else {\n const updated = await db\n .update(t)\n .set({\n status: 'failed',\n finishedAt: Date.now(),\n lockedUntil: null,\n lastError: e.message,\n ...terminalPatch(def),\n })\n .where(ownershipPredicate(row.id, owner))\n .returning({ id: t.id })\n if (!updated[0]) return 'lost'\n logger.error(\n JSON.stringify(\n jobEvent('job.failed', row, {\n durationMs: Date.now() - startedAt,\n error: e.message,\n }),\n ),\n )\n await fireOnFailed(def, input, e)\n }\n return 'failed'\n }\n }\n\n async function runClaimable(now: number): Promise<TickResult> {\n const claimedWork: ClaimedWork[] = []\n let totalClaimed = 0\n for (const [name, def] of Object.entries(defs)) {\n const type = def.kind === 'cron' ? `${CRON_PREFIX}${name}` : name\n const claimed = await claimAvailable(type, def, now)\n totalClaimed += claimed.length\n claimedWork.push(...claimed)\n }\n // Claim the whole tick snapshot before starting any handler. Work enqueued\n // by a handler therefore belongs to the next tick, regardless of the\n // declaration order of its target job type.\n const outcomes = await Promise.all(\n claimedWork.map(({ row, def, owner }) => runJob(row, def, now, owner)),\n )\n let ran = 0\n let failed = 0\n for (const outcome of outcomes) {\n if (outcome === 'ran') ran++\n else if (outcome === 'failed') failed++\n }\n return { claimed: totalClaimed, ran, failed }\n }\n\n async function maintain(now: number) {\n await materializeCronSlots(now)\n await recoverExpiredLeases(now)\n if (now - lastReapAt >= REAP_INTERVAL_MS) {\n lastReapAt = now\n await reapSucceeded(now)\n }\n }\n\n function startWork(\n type: string,\n work: ClaimedWork,\n claimedAt: number,\n ): Promise<void> {\n let tasks = active.get(type)\n if (!tasks) {\n tasks = new Set()\n active.set(type, tasks)\n }\n let task: Promise<void>\n task = runJob(work.row, work.def, claimedAt, work.owner)\n .then(() => undefined)\n .catch((error) => {\n logger.error('[workerstack] background job execution failed:', error)\n })\n .finally(() => {\n tasks!.delete(task)\n if (tasks!.size === 0) active.delete(type)\n })\n tasks.add(task)\n return task\n }\n\n async function pump(now: number = Date.now()): Promise<PumpResult> {\n await maintain(now)\n for (const [name, def] of Object.entries(defs)) {\n const type = def.kind === 'cron' ? `${CRON_PREFIX}${name}` : name\n const work = await claimAvailable(type, def, now)\n for (const item of work) startWork(type, item, now)\n }\n const snapshot = [...active.values()].flatMap((tasks) => [...tasks])\n return snapshot.length === 0\n ? {}\n : { wake: Promise.race(snapshot).then(() => undefined) }\n }\n\n async function drain(): Promise<void> {\n const snapshot = [...active.values()].flatMap((tasks) => [...tasks])\n await Promise.allSettled(snapshot)\n }\n\n return {\n async tick(now: number = Date.now()): Promise<TickResult> {\n await maintain(now)\n return runClaimable(now)\n },\n pump,\n drain,\n /**\n * The earliest time that has work: a pending run_at, a running lease end,\n * or a cron slot not yet materialized. Never earlier than `now`; null when\n * nothing is due before `until`.\n */\n async nextDueAt(now: number, until: number): Promise<number | null> {\n const candidates: number[] = []\n const [pending] = await db\n .select({ at: sql<number | string | null>`min(${t.runAt})` })\n .from(t)\n .where(eq(t.status, 'pending'))\n if (pending?.at != null) candidates.push(Number(pending.at))\n const [running] = await db\n .select({ at: sql<number | string | null>`min(${t.lockedUntil})` })\n .from(t)\n .where(eq(t.status, 'running'))\n if (running?.at != null) candidates.push(Number(running.at))\n for (const [name, def] of Object.entries(defs)) {\n if (def.kind !== 'cron') continue\n const cursor = await cronCursor(`${CRON_PREFIX}${name}`, now)\n const slot = nextCronSlot(\n parseCron(def.schedule),\n cursor.checkedThrough,\n until,\n )\n if (slot !== null) candidates.push(slot)\n }\n if (candidates.length === 0) return null\n return Math.max(now, Math.min(...candidates))\n },\n async inspect(now: number) {\n const runnableRows = await db\n .select({ id: t.id })\n .from(t)\n .where(and(eq(t.status, 'pending'), lte(t.runAt, now)))\n const failed: Array<{\n id: string\n type: string\n attempts: number\n lastError: string | null\n }> = await db\n .select({\n id: t.id,\n type: t.type,\n attempts: t.attempts,\n lastError: t.lastError,\n })\n .from(t)\n .where(eq(t.status, 'failed'))\n const rows: Array<{\n id: string\n type: string\n status: string\n attempts: number\n runAt: number\n dedupeKey: string | null\n lastError: string | null\n createdAt: number\n }> = await db\n .select({\n id: t.id,\n type: t.type,\n status: t.status,\n attempts: t.attempts,\n runAt: t.runAt,\n dedupeKey: t.dedupeKey,\n lastError: t.lastError,\n createdAt: t.createdAt,\n })\n .from(t)\n return {\n runnable: runnableRows.length,\n failed: failed.map((row) => ({\n id: String(row.id),\n name: row.type.startsWith(CRON_PREFIX)\n ? row.type.slice(CRON_PREFIX.length)\n : row.type,\n attempts: Number(row.attempts),\n lastError: row.lastError,\n })),\n jobs: rows\n .sort(\n (left, right) =>\n Number(left.createdAt) - Number(right.createdAt) ||\n String(left.id).localeCompare(String(right.id)),\n )\n .map((row) => ({\n id: String(row.id),\n name: row.type.startsWith(CRON_PREFIX)\n ? row.type.slice(CRON_PREFIX.length)\n : row.type,\n kind: row.type.startsWith(CRON_PREFIX)\n ? ('cron' as const)\n : ('job' as const),\n status: row.status as\n | 'pending'\n | 'running'\n | 'succeeded'\n | 'failed',\n attempts: Number(row.attempts),\n runAt: Number(row.runAt),\n dedupeKey: row.dedupeKey,\n lastError: row.lastError,\n })),\n }\n },\n setJobsFacade(f: JobsRuntimeFacade) {\n ctx.jobs = f\n },\n }\n}\n"]}
@@ -0,0 +1,10 @@
1
+ export type Cleanup = () => void | Promise<void>;
2
+ export type LifecycleStatus = 'ready' | 'closing' | 'closed';
3
+ export declare class Lifecycle {
4
+ #private;
5
+ get signal(): AbortSignal;
6
+ get status(): LifecycleStatus;
7
+ add(cleanup: Cleanup): () => void;
8
+ close(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAChD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE5D,qBAAa,SAAS;;IAMpB,IAAI,MAAM,IAAI,WAAW,CAExB;IAED,IAAI,MAAM,IAAI,eAAe,CAE5B;IAED,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,IAAI;IAQjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBvB"}
@@ -0,0 +1,37 @@
1
+ export class Lifecycle {
2
+ #controller = new AbortController();
3
+ #status = 'ready';
4
+ #cleanups = new Set();
5
+ #closePromise;
6
+ get signal() {
7
+ return this.#controller.signal;
8
+ }
9
+ get status() {
10
+ return this.#status;
11
+ }
12
+ add(cleanup) {
13
+ if (this.#status !== 'ready') {
14
+ throw new Error('[workerstack] application lifecycle is closed');
15
+ }
16
+ this.#cleanups.add(cleanup);
17
+ return () => this.#cleanups.delete(cleanup);
18
+ }
19
+ close() {
20
+ if (this.#closePromise)
21
+ return this.#closePromise;
22
+ this.#status = 'closing';
23
+ this.#controller.abort();
24
+ this.#closePromise = (async () => {
25
+ const cleanups = [...this.#cleanups].reverse();
26
+ this.#cleanups.clear();
27
+ const results = await Promise.allSettled(cleanups.map(async (cleanup) => cleanup()));
28
+ this.#status = 'closed';
29
+ const errors = results.flatMap((result) => result.status === 'rejected' ? [result.reason] : []);
30
+ if (errors.length > 0) {
31
+ throw new AggregateError(errors, '[workerstack] lifecycle cleanup failed');
32
+ }
33
+ })();
34
+ return this.#closePromise;
35
+ }
36
+ }
37
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,SAAS;IACpB,WAAW,GAAG,IAAI,eAAe,EAAE,CAAA;IACnC,OAAO,GAAoB,OAAO,CAAA;IAClC,SAAS,GAAG,IAAI,GAAG,EAAW,CAAA;IAC9B,aAAa,CAA2B;IAExC,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAA;IAChC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,GAAG,CAAC,OAAgB;QAClB,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;QAClE,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC3B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC7C,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC,aAAa,CAAA;QACjD,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QACxB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAA;QACxB,IAAI,CAAC,aAAa,GAAG,CAAC,KAAK,IAAI,EAAE;YAC/B,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAA;YAC9C,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;YACtB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAC3C,CAAA;YACD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAA;YACvB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACxC,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CACpD,CAAA;YACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,cAAc,CACtB,MAAM,EACN,wCAAwC,CACzC,CAAA;YACH,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QACJ,OAAO,IAAI,CAAC,aAAa,CAAA;IAC3B,CAAC;CACF","sourcesContent":["export type Cleanup = () => void | Promise<void>\nexport type LifecycleStatus = 'ready' | 'closing' | 'closed'\n\nexport class Lifecycle {\n #controller = new AbortController()\n #status: LifecycleStatus = 'ready'\n #cleanups = new Set<Cleanup>()\n #closePromise: Promise<void> | undefined\n\n get signal(): AbortSignal {\n return this.#controller.signal\n }\n\n get status(): LifecycleStatus {\n return this.#status\n }\n\n add(cleanup: Cleanup): () => void {\n if (this.#status !== 'ready') {\n throw new Error('[workerstack] application lifecycle is closed')\n }\n this.#cleanups.add(cleanup)\n return () => this.#cleanups.delete(cleanup)\n }\n\n close(): Promise<void> {\n if (this.#closePromise) return this.#closePromise\n this.#status = 'closing'\n this.#controller.abort()\n this.#closePromise = (async () => {\n const cleanups = [...this.#cleanups].reverse()\n this.#cleanups.clear()\n const results = await Promise.allSettled(\n cleanups.map(async (cleanup) => cleanup()),\n )\n this.#status = 'closed'\n const errors = results.flatMap((result) =>\n result.status === 'rejected' ? [result.reason] : [],\n )\n if (errors.length > 0) {\n throw new AggregateError(\n errors,\n '[workerstack] lifecycle cleanup failed',\n )\n }\n })()\n return this.#closePromise\n }\n}\n"]}
@@ -0,0 +1,62 @@
1
+ import { getTableColumns, type SQL } from 'drizzle-orm';
2
+ import type { ResolvedTableAccess, SortOrder } from './access.js';
3
+ import type { AnyDb } from './dialect.js';
4
+ /** Caps both `?limit=` and the number of values in an `IN` filter. */
5
+ export declare const MAX_LIST_LIMIT = 200;
6
+ /** Default page size when a request omits `limit`. */
7
+ export declare const DEFAULT_LIST_LIMIT = 20;
8
+ /**
9
+ * What a list procedure accepts. Shape and column types are enforced by the
10
+ * generated input schema, so by the time these params arrive they are already
11
+ * validated and coerced — this module only applies policy (defaults, the limit
12
+ * cap, cursor rules).
13
+ */
14
+ export type ListParamsInput = {
15
+ limit?: number;
16
+ offset?: number;
17
+ cursor?: string;
18
+ sort?: string;
19
+ order?: SortOrder;
20
+ q?: string;
21
+ count?: boolean;
22
+ filters?: Record<string, unknown>;
23
+ };
24
+ export type ParsedListParams = {
25
+ limit: number;
26
+ offset?: number;
27
+ sort: string;
28
+ order: SortOrder;
29
+ q: string;
30
+ cursor?: string;
31
+ count: boolean;
32
+ filters: Record<string, unknown>;
33
+ };
34
+ export type ListResult<T> = {
35
+ items: T[];
36
+ limit: number;
37
+ offset?: number;
38
+ cursor?: string;
39
+ nextCursor?: string;
40
+ hasMore: boolean;
41
+ total?: number;
42
+ q?: string;
43
+ sort: string;
44
+ order: SortOrder;
45
+ };
46
+ type CursorPayload = {
47
+ sort: string;
48
+ order: SortOrder;
49
+ v: string | number | null;
50
+ id: string | number;
51
+ };
52
+ /**
53
+ * Applies list policy to already-validated input: defaults, the limit cap, and
54
+ * the rules a schema cannot express (cursor excludes offset, and a cursor must
55
+ * agree with the sort it was minted for).
56
+ */
57
+ export declare function resolveListParams(input: ListParamsInput, access: ResolvedTableAccess): ParsedListParams;
58
+ export declare function encodeCursor(payload: CursorPayload): string;
59
+ export declare function decodeCursor(cursor: string): CursorPayload;
60
+ export declare function executeList<T extends Record<string, unknown>>(db: AnyDb, table: Parameters<typeof getTableColumns>[0], access: ResolvedTableAccess, params: ParsedListParams, idCol: unknown, scopeWhere?: SQL): Promise<ListResult<T>>;
61
+ export {};
62
+ //# sourceMappingURL=list-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-query.d.ts","sourceRoot":"","sources":["../src/list-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,eAAe,EAOf,KAAK,GAAG,EACT,MAAM,aAAa,CAAA;AAEpB,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AAItC,sEAAsE;AACtE,eAAO,MAAM,cAAc,MAAM,CAAA;AAEjC,sDAAsD;AACtD,eAAO,MAAM,kBAAkB,KAAK,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,CAAA;IAChB,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,CAAA;CACjB,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,CAAA;IAChB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACzB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CACpB,CAAA;AAkBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,mBAAmB,GAC1B,gBAAgB,CA6BlB;AA8DD,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAE3D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAU1D;AAqCD,wBAAsB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,EAAE,EAAE,KAAK,EACT,KAAK,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,EAC5C,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,OAAO,EACd,UAAU,CAAC,EAAE,GAAG,GACf,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CA+ExB"}
@@ -0,0 +1,190 @@
1
+ import { and, asc, desc, eq, getTableColumns, gt, inArray, like, lt, or, sql, } from 'drizzle-orm';
2
+ import { ErrorCode, ListQueryError } from './errors.js';
3
+ /** Caps both `?limit=` and the number of values in an `IN` filter. */
4
+ export const MAX_LIST_LIMIT = 200;
5
+ /** Default page size when a request omits `limit`. */
6
+ export const DEFAULT_LIST_LIMIT = 20;
7
+ function isRecord(value) {
8
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
9
+ }
10
+ function isCursorPayload(value) {
11
+ if (!isRecord(value))
12
+ return false;
13
+ return (typeof value.sort === 'string' &&
14
+ (value.order === 'asc' || value.order === 'desc') &&
15
+ (value.v === null ||
16
+ typeof value.v === 'string' ||
17
+ typeof value.v === 'number') &&
18
+ (typeof value.id === 'string' || typeof value.id === 'number'));
19
+ }
20
+ /**
21
+ * Applies list policy to already-validated input: defaults, the limit cap, and
22
+ * the rules a schema cannot express (cursor excludes offset, and a cursor must
23
+ * agree with the sort it was minted for).
24
+ */
25
+ export function resolveListParams(input, access) {
26
+ const cursor = input.cursor?.trim() || undefined;
27
+ if (cursor && input.offset !== undefined) {
28
+ throw new ListQueryError('cursor and offset cannot be used together');
29
+ }
30
+ const sort = input.sort ?? access.defaultSort.column;
31
+ const order = input.order ?? (input.sort ? 'asc' : access.defaultSort.order);
32
+ if (cursor) {
33
+ const decoded = decodeCursor(cursor);
34
+ if (decoded.sort !== sort || decoded.order !== order) {
35
+ throw new ListQueryError('cursor does not match sort and order parameters', ErrorCode.INVALID_CURSOR);
36
+ }
37
+ }
38
+ return {
39
+ limit: Math.min(input.limit ?? DEFAULT_LIST_LIMIT, MAX_LIST_LIMIT),
40
+ offset: cursor ? undefined : (input.offset ?? 0),
41
+ sort,
42
+ order,
43
+ q: input.q?.trim() ?? '',
44
+ cursor,
45
+ count: input.count ?? false,
46
+ filters: input.filters ?? {},
47
+ };
48
+ }
49
+ function buildSearchWhere(table, searchableColumns, q) {
50
+ if (!q || !searchableColumns?.length)
51
+ return undefined;
52
+ const columns = getTableColumns(table);
53
+ const pattern = `%${q.replace(/[%_\\]/g, (ch) => `\\${ch}`)}%`;
54
+ const conditions = searchableColumns
55
+ .filter((name) => name in columns)
56
+ .map((name) => like(columns[name], pattern));
57
+ return conditions.length ? or(...conditions) : undefined;
58
+ }
59
+ /**
60
+ * Cursors carry their sort value as JSON, so a date column arrives as a string
61
+ * and has to be rebuilt. Filter values need no such repair — the generated
62
+ * input schema already types them.
63
+ */
64
+ function coerceCursorValue(table, columnName, raw) {
65
+ if (raw === null)
66
+ return null;
67
+ const col = getTableColumns(table)[columnName];
68
+ if (col?.dataType === 'date')
69
+ return new Date(raw);
70
+ return raw;
71
+ }
72
+ function buildFilterWhere(table, filters) {
73
+ const columns = getTableColumns(table);
74
+ const conditions = [];
75
+ for (const [name, value] of Object.entries(filters)) {
76
+ const col = columns[name];
77
+ if (!col || value === undefined)
78
+ continue;
79
+ if (value === null) {
80
+ conditions.push(sql `${col} IS NULL`);
81
+ }
82
+ else if (Array.isArray(value)) {
83
+ if (value.length)
84
+ conditions.push(inArray(col, value));
85
+ }
86
+ else {
87
+ conditions.push(eq(col, value));
88
+ }
89
+ }
90
+ return conditions.length ? and(...conditions) : undefined;
91
+ }
92
+ function serializeCursorValue(value) {
93
+ if (value == null)
94
+ return null;
95
+ if (value instanceof Date)
96
+ return value.toISOString();
97
+ if (typeof value === 'number' || typeof value === 'string')
98
+ return value;
99
+ return String(value);
100
+ }
101
+ export function encodeCursor(payload) {
102
+ return Buffer.from(JSON.stringify(payload)).toString('base64url');
103
+ }
104
+ export function decodeCursor(cursor) {
105
+ try {
106
+ const parsed = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'));
107
+ if (!isCursorPayload(parsed)) {
108
+ throw new Error('invalid cursor shape');
109
+ }
110
+ return parsed;
111
+ }
112
+ catch {
113
+ throw new ListQueryError('invalid cursor', ErrorCode.INVALID_CURSOR);
114
+ }
115
+ }
116
+ function buildCursorWhere(table, sortColName, order, cursor, idCol) {
117
+ const columns = getTableColumns(table);
118
+ const sortCol = columns[sortColName];
119
+ const sortValue = coerceCursorValue(table, sortColName, cursor.v);
120
+ if (order === 'desc') {
121
+ return or(lt(sortCol, sortValue), and(eq(sortCol, sortValue), lt(idCol, cursor.id)));
122
+ }
123
+ return or(gt(sortCol, sortValue), and(eq(sortCol, sortValue), gt(idCol, cursor.id)));
124
+ }
125
+ function buildOrderBy(table, sortColName, order, idCol) {
126
+ const columns = getTableColumns(table);
127
+ const sortCol = columns[sortColName];
128
+ const idOrder = order === 'asc' ? asc(idCol) : desc(idCol);
129
+ return order === 'asc' ? [asc(sortCol), idOrder] : [desc(sortCol), idOrder];
130
+ }
131
+ export async function executeList(db, table, access, params, idCol, scopeWhere) {
132
+ const searchWhere = buildSearchWhere(table, access.searchableColumns, params.q);
133
+ const filterWhere = buildFilterWhere(table, params.filters);
134
+ let where = and(...(searchWhere ? [searchWhere] : []), ...(filterWhere ? [filterWhere] : []), ...(scopeWhere ? [scopeWhere] : []));
135
+ if (params.cursor) {
136
+ const cursorPayload = decodeCursor(params.cursor);
137
+ const cursorWhere = buildCursorWhere(table, params.sort, params.order, cursorPayload, idCol);
138
+ where = where ? and(where, cursorWhere) : cursorWhere;
139
+ }
140
+ const orderBy = buildOrderBy(table, params.sort, params.order, idCol);
141
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
+ let query = db.select().from(table);
143
+ if (where)
144
+ query = query.where(where);
145
+ query = query.orderBy(...orderBy);
146
+ if (params.offset !== undefined) {
147
+ query = query.limit(params.limit).offset(params.offset);
148
+ }
149
+ else {
150
+ query = query.limit(params.limit);
151
+ }
152
+ const items = (await query);
153
+ let total;
154
+ if (params.count) {
155
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
156
+ let countQuery = db
157
+ .select({ count: sql `count(*)` })
158
+ .from(table);
159
+ if (where)
160
+ countQuery = countQuery.where(where);
161
+ const [row] = await countQuery;
162
+ total = Number(row?.count ?? 0);
163
+ }
164
+ const hasMore = total !== undefined && params.offset !== undefined
165
+ ? params.offset + items.length < total
166
+ : items.length === params.limit;
167
+ let nextCursor;
168
+ if (items.length === params.limit) {
169
+ const last = items[items.length - 1];
170
+ nextCursor = encodeCursor({
171
+ sort: params.sort,
172
+ order: params.order,
173
+ v: serializeCursorValue(last[params.sort]),
174
+ id: last.id,
175
+ });
176
+ }
177
+ return {
178
+ items,
179
+ limit: params.limit,
180
+ ...(params.offset !== undefined ? { offset: params.offset } : {}),
181
+ ...(params.cursor ? { cursor: params.cursor } : {}),
182
+ ...(nextCursor ? { nextCursor } : {}),
183
+ hasMore,
184
+ ...(total !== undefined ? { total } : {}),
185
+ ...(params.q ? { q: params.q } : {}),
186
+ sort: params.sort,
187
+ order: params.order,
188
+ };
189
+ }
190
+ //# sourceMappingURL=list-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-query.js","sourceRoot":"","sources":["../src/list-query.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n and,\n asc,\n desc,\n eq,\n getTableColumns,\n gt,\n inArray,\n like,\n lt,\n or,\n sql,\n type SQL,\n} from 'drizzle-orm'\n\nimport type { ResolvedTableAccess, SortOrder } from './access'\nimport type { AnyDb } from './dialect'\n\nimport { ErrorCode, ListQueryError } from './errors'\n\n/** Caps both `?limit=` and the number of values in an `IN` filter. */\nexport const MAX_LIST_LIMIT = 200\n\n/** Default page size when a request omits `limit`. */\nexport const DEFAULT_LIST_LIMIT = 20\n\n/**\n * What a list procedure accepts. Shape and column types are enforced by the\n * generated input schema, so by the time these params arrive they are already\n * validated and coerced — this module only applies policy (defaults, the limit\n * cap, cursor rules).\n */\nexport type ListParamsInput = {\n limit?: number\n offset?: number\n cursor?: string\n sort?: string\n order?: SortOrder\n q?: string\n count?: boolean\n filters?: Record<string, unknown>\n}\n\nexport type ParsedListParams = {\n limit: number\n offset?: number\n sort: string\n order: SortOrder\n q: string\n cursor?: string\n count: boolean\n filters: Record<string, unknown>\n}\n\nexport type ListResult<T> = {\n items: T[]\n limit: number\n offset?: number\n cursor?: string\n nextCursor?: string\n hasMore: boolean\n total?: number\n q?: string\n sort: string\n order: SortOrder\n}\n\ntype CursorPayload = {\n sort: string\n order: SortOrder\n v: string | number | null\n id: string | number\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction isCursorPayload(value: unknown): value is CursorPayload {\n if (!isRecord(value)) return false\n return (\n typeof value.sort === 'string' &&\n (value.order === 'asc' || value.order === 'desc') &&\n (value.v === null ||\n typeof value.v === 'string' ||\n typeof value.v === 'number') &&\n (typeof value.id === 'string' || typeof value.id === 'number')\n )\n}\n\n/**\n * Applies list policy to already-validated input: defaults, the limit cap, and\n * the rules a schema cannot express (cursor excludes offset, and a cursor must\n * agree with the sort it was minted for).\n */\nexport function resolveListParams(\n input: ListParamsInput,\n access: ResolvedTableAccess,\n): ParsedListParams {\n const cursor = input.cursor?.trim() || undefined\n if (cursor && input.offset !== undefined) {\n throw new ListQueryError('cursor and offset cannot be used together')\n }\n\n const sort = input.sort ?? access.defaultSort.column\n const order = input.order ?? (input.sort ? 'asc' : access.defaultSort.order)\n\n if (cursor) {\n const decoded = decodeCursor(cursor)\n if (decoded.sort !== sort || decoded.order !== order) {\n throw new ListQueryError(\n 'cursor does not match sort and order parameters',\n ErrorCode.INVALID_CURSOR,\n )\n }\n }\n\n return {\n limit: Math.min(input.limit ?? DEFAULT_LIST_LIMIT, MAX_LIST_LIMIT),\n offset: cursor ? undefined : (input.offset ?? 0),\n sort,\n order,\n q: input.q?.trim() ?? '',\n cursor,\n count: input.count ?? false,\n filters: input.filters ?? {},\n }\n}\n\nfunction buildSearchWhere(\n table: Parameters<typeof getTableColumns>[0],\n searchableColumns: string[] | undefined,\n q: string,\n): SQL | undefined {\n if (!q || !searchableColumns?.length) return undefined\n const columns = getTableColumns(table)\n const pattern = `%${q.replace(/[%_\\\\]/g, (ch) => `\\\\${ch}`)}%`\n const conditions = searchableColumns\n .filter((name) => name in columns)\n .map((name) => like(columns[name]!, pattern))\n return conditions.length ? or(...conditions) : undefined\n}\n\n/**\n * Cursors carry their sort value as JSON, so a date column arrives as a string\n * and has to be rebuilt. Filter values need no such repair — the generated\n * input schema already types them.\n */\nfunction coerceCursorValue(\n table: Parameters<typeof getTableColumns>[0],\n columnName: string,\n raw: string | number | null,\n): unknown {\n if (raw === null) return null\n const col = getTableColumns(table)[columnName]\n if (col?.dataType === 'date') return new Date(raw)\n return raw\n}\n\nfunction buildFilterWhere(\n table: Parameters<typeof getTableColumns>[0],\n filters: Record<string, unknown>,\n): SQL | undefined {\n const columns = getTableColumns(table)\n const conditions: SQL[] = []\n\n for (const [name, value] of Object.entries(filters)) {\n const col = columns[name]\n if (!col || value === undefined) continue\n\n if (value === null) {\n conditions.push(sql`${col} IS NULL`)\n } else if (Array.isArray(value)) {\n if (value.length) conditions.push(inArray(col, value))\n } else {\n conditions.push(eq(col, value))\n }\n }\n\n return conditions.length ? and(...conditions) : undefined\n}\n\nfunction serializeCursorValue(value: unknown): string | number | null {\n if (value == null) return null\n if (value instanceof Date) return value.toISOString()\n if (typeof value === 'number' || typeof value === 'string') return value\n return String(value)\n}\n\nexport function encodeCursor(payload: CursorPayload): string {\n return Buffer.from(JSON.stringify(payload)).toString('base64url')\n}\n\nexport function decodeCursor(cursor: string): CursorPayload {\n try {\n const parsed = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'))\n if (!isCursorPayload(parsed)) {\n throw new Error('invalid cursor shape')\n }\n return parsed\n } catch {\n throw new ListQueryError('invalid cursor', ErrorCode.INVALID_CURSOR)\n }\n}\n\nfunction buildCursorWhere(\n table: Parameters<typeof getTableColumns>[0],\n sortColName: string,\n order: SortOrder,\n cursor: CursorPayload,\n idCol: unknown,\n): SQL {\n const columns = getTableColumns(table)\n const sortCol = columns[sortColName]!\n const sortValue = coerceCursorValue(table, sortColName, cursor.v)\n\n if (order === 'desc') {\n return or(\n lt(sortCol, sortValue),\n and(eq(sortCol, sortValue), lt(idCol as never, cursor.id)),\n )!\n }\n return or(\n gt(sortCol, sortValue),\n and(eq(sortCol, sortValue), gt(idCol as never, cursor.id)),\n )!\n}\n\nfunction buildOrderBy(\n table: Parameters<typeof getTableColumns>[0],\n sortColName: string,\n order: SortOrder,\n idCol: unknown,\n) {\n const columns = getTableColumns(table)\n const sortCol = columns[sortColName]!\n const idOrder = order === 'asc' ? asc(idCol as never) : desc(idCol as never)\n return order === 'asc' ? [asc(sortCol), idOrder] : [desc(sortCol), idOrder]\n}\n\nexport async function executeList<T extends Record<string, unknown>>(\n db: AnyDb,\n table: Parameters<typeof getTableColumns>[0],\n access: ResolvedTableAccess,\n params: ParsedListParams,\n idCol: unknown,\n scopeWhere?: SQL,\n): Promise<ListResult<T>> {\n const searchWhere = buildSearchWhere(\n table,\n access.searchableColumns,\n params.q,\n )\n const filterWhere = buildFilterWhere(table, params.filters)\n let where = and(\n ...(searchWhere ? [searchWhere] : []),\n ...(filterWhere ? [filterWhere] : []),\n ...(scopeWhere ? [scopeWhere] : []),\n )\n\n if (params.cursor) {\n const cursorPayload = decodeCursor(params.cursor)\n const cursorWhere = buildCursorWhere(\n table,\n params.sort,\n params.order,\n cursorPayload,\n idCol,\n )\n where = where ? and(where, cursorWhere) : cursorWhere\n }\n\n const orderBy = buildOrderBy(table, params.sort, params.order, idCol)\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let query = (db as any).select().from(table)\n if (where) query = query.where(where)\n query = query.orderBy(...orderBy)\n\n if (params.offset !== undefined) {\n query = query.limit(params.limit).offset(params.offset)\n } else {\n query = query.limit(params.limit)\n }\n\n const items = (await query) as T[]\n\n let total: number | undefined\n if (params.count) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let countQuery = (db as any)\n .select({ count: sql<number>`count(*)` })\n .from(table)\n if (where) countQuery = countQuery.where(where)\n const [row] = await countQuery\n total = Number(row?.count ?? 0)\n }\n\n const hasMore =\n total !== undefined && params.offset !== undefined\n ? params.offset + items.length < total\n : items.length === params.limit\n\n let nextCursor: string | undefined\n if (items.length === params.limit) {\n const last = items[items.length - 1]!\n nextCursor = encodeCursor({\n sort: params.sort,\n order: params.order,\n v: serializeCursorValue(last[params.sort]),\n id: last.id as string | number,\n })\n }\n\n return {\n items,\n limit: params.limit,\n ...(params.offset !== undefined ? { offset: params.offset } : {}),\n ...(params.cursor ? { cursor: params.cursor } : {}),\n ...(nextCursor ? { nextCursor } : {}),\n hasMore,\n ...(total !== undefined ? { total } : {}),\n ...(params.q ? { q: params.q } : {}),\n sort: params.sort,\n order: params.order,\n }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { LiveFrame } from './protocol.js';
2
+ /**
3
+ * One frame folded into a view's rows.
4
+ *
5
+ * Pure and immutable: a changed view is a new array, an unchanged view is the
6
+ * same array, and a row the frame did not touch keeps its identity. That is
7
+ * what `useSyncExternalStore` and a keyed list need to skip the rows a frame
8
+ * did not change.
9
+ */
10
+ export declare function applyLiveFrame<TRow extends {
11
+ id: string;
12
+ }>(rows: readonly TRow[], frame: LiveFrame<TRow>): readonly TRow[];
13
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/live/apply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACxD,IAAI,EAAE,SAAS,IAAI,EAAE,EACrB,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,GACrB,SAAS,IAAI,EAAE,CAqBjB"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * One frame folded into a view's rows.
3
+ *
4
+ * Pure and immutable: a changed view is a new array, an unchanged view is the
5
+ * same array, and a row the frame did not touch keeps its identity. That is
6
+ * what `useSyncExternalStore` and a keyed list need to skip the rows a frame
7
+ * did not change.
8
+ */
9
+ export function applyLiveFrame(rows, frame) {
10
+ if (frame.type === 'snapshot')
11
+ return frame.items;
12
+ if (frame.type === 'heartbeat')
13
+ return rows;
14
+ if (frame.type === 'remove') {
15
+ const next = rows.filter((row) => row.id !== frame.id);
16
+ return next.length === rows.length ? rows : next;
17
+ }
18
+ // An upsert can move a row, so the stale copy goes first.
19
+ const next = rows.filter((row) => row.id !== frame.record.id);
20
+ let place;
21
+ if (frame.afterId === null) {
22
+ place = 0;
23
+ }
24
+ else {
25
+ const anchor = next.findIndex((row) => row.id === frame.afterId);
26
+ // An anchor the view does not hold means the row belongs at the end.
27
+ place = anchor === -1 ? next.length : anchor + 1;
28
+ }
29
+ next.splice(place, 0, frame.record);
30
+ return next;
31
+ }
32
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/live/apply.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAqB,EACrB,KAAsB;IAEtB,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC,KAAK,CAAA;IACjD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAA;IAE3C,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAA;QACtD,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;IAClD,CAAC;IAED,0DAA0D;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC7D,IAAI,KAAa,CAAA;IACjB,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC3B,KAAK,GAAG,CAAC,CAAA;IACX,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,OAAO,CAAC,CAAA;QAChE,qEAAqE;QACrE,KAAK,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;IAClD,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACnC,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import type { LiveFrame } from './protocol'\n\n/**\n * One frame folded into a view's rows.\n *\n * Pure and immutable: a changed view is a new array, an unchanged view is the\n * same array, and a row the frame did not touch keeps its identity. That is\n * what `useSyncExternalStore` and a keyed list need to skip the rows a frame\n * did not change.\n */\nexport function applyLiveFrame<TRow extends { id: string }>(\n rows: readonly TRow[],\n frame: LiveFrame<TRow>,\n): readonly TRow[] {\n if (frame.type === 'snapshot') return frame.items\n if (frame.type === 'heartbeat') return rows\n\n if (frame.type === 'remove') {\n const next = rows.filter((row) => row.id !== frame.id)\n return next.length === rows.length ? rows : next\n }\n\n // An upsert can move a row, so the stale copy goes first.\n const next = rows.filter((row) => row.id !== frame.record.id)\n let place: number\n if (frame.afterId === null) {\n place = 0\n } else {\n const anchor = next.findIndex((row) => row.id === frame.afterId)\n // An anchor the view does not hold means the row belongs at the end.\n place = anchor === -1 ? next.length : anchor + 1\n }\n next.splice(place, 0, frame.record)\n return next\n}\n"]}
@@ -0,0 +1,48 @@
1
+ import type { LiveInput } from './protocol.js';
2
+ export type { LiveDeltaFrame, LiveFrame, LiveHeartbeatFrame, LiveInput, LiveRemoveFrame, LiveSnapshotFrame, LiveUpsertFrame, } from './protocol.js';
3
+ export { applyLiveFrame } from './apply.js';
4
+ export { parseSseFrames, type ByteStream } from './sse.js';
5
+ export type LiveStatus = 'connecting' | 'live' | 'reconnecting' | 'failed';
6
+ export type LiveView<TRow extends {
7
+ id: string;
8
+ }> = {
9
+ /** The current rows. A new array appears only when the view changes. */
10
+ getRows: () => readonly TRow[];
11
+ getStatus: () => LiveStatus;
12
+ getError: () => unknown;
13
+ /** Register a listener; the return value removes it. */
14
+ subscribe: (listener: () => void) => () => void;
15
+ /**
16
+ * Write to the view before the server confirms. Replace a row rather than
17
+ * mutating it, so consumers that compare by identity see the change:
18
+ * `patch((rows) => { rows[0] = { ...rows[0], done: true } })`.
19
+ * The server echo replaces the write, and `resync()` discards it.
20
+ */
21
+ patch: (recipe: (rows: TRow[]) => void) => void;
22
+ /** Reconnect. The new snapshot is the resynchronisation. */
23
+ resync: () => void;
24
+ /** Stop the loop and abort the request. */
25
+ close: () => void;
26
+ };
27
+ export type CreateLiveViewOptions = {
28
+ input?: LiveInput;
29
+ /** For tests, and for a fetch that carries credentials or a base URL. */
30
+ fetch?: (input: string, init?: RequestInit) => Promise<Response>;
31
+ /** Delay in milliseconds before retry number `attempt`, counted from zero. */
32
+ backoff?: (attempt: number) => number;
33
+ };
34
+ /**
35
+ * One live view: a reconnecting loop over `GET /api/live/{table}` that folds
36
+ * frames into an immutable array of rows.
37
+ *
38
+ * The view holds no cache and no second copy of the data. Every connection
39
+ * opens with a snapshot, so a reconnect is the resynchronisation, and the
40
+ * server places each row, so this module never sorts.
41
+ *
42
+ * `subscribe` plus `getRows` is the pair `useSyncExternalStore` expects. A
43
+ * Solid or Vue binding writes `getRows()` into a store from the same listener.
44
+ */
45
+ export declare function createLiveView<TRow extends {
46
+ id: string;
47
+ }>(url: string, options?: CreateLiveViewOptions): LiveView<TRow>;
48
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/live/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,YAAY,CAAA;AAKtD,YAAY,EACV,cAAc,EACd,SAAS,EACT,kBAAkB,EAClB,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAA;AAEvD,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,MAAM,GAAG,cAAc,GAAG,QAAQ,CAAA;AAE1E,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,IAAI;IAClD,wEAAwE;IACxE,OAAO,EAAE,MAAM,SAAS,IAAI,EAAE,CAAA;IAC9B,SAAS,EAAE,MAAM,UAAU,CAAA;IAC3B,QAAQ,EAAE,MAAM,OAAO,CAAA;IACvB,wDAAwD;IACxD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;IAC/C;;;;;OAKG;IACH,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,IAAI,CAAA;IAC/C,4DAA4D;IAC5D,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,yEAAyE;IACzE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAChE,8EAA8E;IAC9E,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;CACtC,CAAA;AAoBD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACxD,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,qBAA0B,GAClC,QAAQ,CAAC,IAAI,CAAC,CA4EhB"}