velocious 1.0.430 → 1.0.432

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 (831) hide show
  1. package/bin/velocious.js +48 -0
  2. package/build/application.js +229 -0
  3. package/build/authorization/ability.js +329 -0
  4. package/build/authorization/base-resource.js +143 -0
  5. package/build/background-jobs/client.js +50 -0
  6. package/build/background-jobs/cron-expression.js +277 -0
  7. package/build/background-jobs/forked-runner-child.js +86 -0
  8. package/build/background-jobs/job-record.js +13 -0
  9. package/build/background-jobs/job-registry.js +92 -0
  10. package/build/background-jobs/job-runner.js +107 -0
  11. package/build/background-jobs/job.js +77 -0
  12. package/build/background-jobs/json-socket.js +78 -0
  13. package/build/background-jobs/main.js +926 -0
  14. package/build/background-jobs/normalize-error.js +26 -0
  15. package/build/background-jobs/scheduler.js +274 -0
  16. package/build/background-jobs/socket-request.js +68 -0
  17. package/build/background-jobs/status-reporter.js +101 -0
  18. package/build/background-jobs/store.js +994 -0
  19. package/build/background-jobs/types.js +70 -0
  20. package/build/background-jobs/web/authorization.js +89 -0
  21. package/build/background-jobs/web/controller.js +280 -0
  22. package/build/background-jobs/web/index.js +57 -0
  23. package/build/background-jobs/web/path-matcher.js +74 -0
  24. package/build/background-jobs/web/registry.js +49 -0
  25. package/build/background-jobs/worker.js +683 -0
  26. package/build/beacon/client.js +330 -0
  27. package/build/beacon/in-process-broker.js +71 -0
  28. package/build/beacon/in-process-client.js +139 -0
  29. package/build/beacon/server.js +148 -0
  30. package/build/beacon/types.js +55 -0
  31. package/build/bin/velocious.js +39 -34
  32. package/build/cli/base-command.js +67 -0
  33. package/build/cli/browser-cli.js +45 -0
  34. package/build/cli/commands/background-jobs-main.js +7 -0
  35. package/build/cli/commands/background-jobs-runner.js +7 -0
  36. package/build/cli/commands/background-jobs-worker.js +7 -0
  37. package/build/cli/commands/beacon.js +7 -0
  38. package/build/cli/commands/console.js +12 -0
  39. package/build/cli/commands/db/base-command.js +82 -0
  40. package/build/cli/commands/db/create.js +64 -0
  41. package/build/cli/commands/db/drop.js +75 -0
  42. package/build/cli/commands/db/migrate.js +17 -0
  43. package/build/cli/commands/db/reset.js +22 -0
  44. package/build/cli/commands/db/rollback.js +15 -0
  45. package/build/cli/commands/db/schema/dump.js +12 -0
  46. package/build/cli/commands/db/schema/load.js +12 -0
  47. package/build/cli/commands/db/seed.js +12 -0
  48. package/build/cli/commands/db/tenants/check.js +38 -0
  49. package/build/cli/commands/db/tenants/create.js +33 -0
  50. package/build/cli/commands/db/tenants/migrate.js +49 -0
  51. package/build/cli/commands/destroy/migration.js +7 -0
  52. package/build/cli/commands/generate/base-models.js +7 -0
  53. package/build/cli/commands/generate/frontend-models.js +12 -0
  54. package/build/cli/commands/generate/migration.js +7 -0
  55. package/build/cli/commands/generate/model.js +7 -0
  56. package/build/cli/commands/init.js +11 -0
  57. package/build/cli/commands/routes.js +7 -0
  58. package/build/cli/commands/run-script.js +12 -0
  59. package/build/cli/commands/runner.js +12 -0
  60. package/build/cli/commands/server.js +7 -0
  61. package/build/cli/commands/test.js +9 -0
  62. package/build/cli/index.js +152 -0
  63. package/build/cli/tenant-database-command-helper.js +198 -0
  64. package/build/cli/use-browser-cli.js +30 -0
  65. package/build/configuration-resolver.js +65 -0
  66. package/build/configuration-types.js +429 -0
  67. package/build/configuration.js +2590 -0
  68. package/build/controller.js +421 -0
  69. package/build/current-configuration.js +31 -0
  70. package/build/current.js +80 -0
  71. package/build/database/annotations-async-hooks.js +47 -0
  72. package/build/database/annotations.js +40 -0
  73. package/build/database/drivers/base-column.js +182 -0
  74. package/build/database/drivers/base-columns-index.js +81 -0
  75. package/build/database/drivers/base-foreign-key.js +104 -0
  76. package/build/database/drivers/base-table.js +156 -0
  77. package/build/database/drivers/base.js +1609 -0
  78. package/build/database/drivers/mssql/column.js +74 -0
  79. package/build/database/drivers/mssql/columns-index.js +6 -0
  80. package/build/database/drivers/mssql/connect-connection.js +16 -0
  81. package/build/database/drivers/mssql/foreign-key.js +12 -0
  82. package/build/database/drivers/mssql/index.js +590 -0
  83. package/build/database/drivers/mssql/options.js +79 -0
  84. package/build/database/drivers/mssql/query-parser.js +6 -0
  85. package/build/database/drivers/mssql/sql/alter-table.js +4 -0
  86. package/build/database/drivers/mssql/sql/create-database.js +36 -0
  87. package/build/database/drivers/mssql/sql/create-index.js +4 -0
  88. package/build/database/drivers/mssql/sql/create-table.js +4 -0
  89. package/build/database/drivers/mssql/sql/delete.js +19 -0
  90. package/build/database/drivers/mssql/sql/drop-database.js +36 -0
  91. package/build/database/drivers/mssql/sql/drop-table.js +4 -0
  92. package/build/database/drivers/mssql/sql/insert.js +4 -0
  93. package/build/database/drivers/mssql/sql/update.js +31 -0
  94. package/build/database/drivers/mssql/sql/upsert.js +23 -0
  95. package/build/database/drivers/mssql/structure-sql.js +120 -0
  96. package/build/database/drivers/mssql/table.js +145 -0
  97. package/build/database/drivers/mysql/column.js +112 -0
  98. package/build/database/drivers/mysql/columns-index.js +22 -0
  99. package/build/database/drivers/mysql/foreign-key.js +12 -0
  100. package/build/database/drivers/mysql/index.js +473 -0
  101. package/build/database/drivers/mysql/options.js +34 -0
  102. package/build/database/drivers/mysql/query-parser.js +6 -0
  103. package/build/database/drivers/mysql/query.js +37 -0
  104. package/build/database/drivers/mysql/sql/alter-table.js +6 -0
  105. package/build/database/drivers/mysql/sql/create-database.js +39 -0
  106. package/build/database/drivers/mysql/sql/create-index.js +6 -0
  107. package/build/database/drivers/mysql/sql/create-table.js +6 -0
  108. package/build/database/drivers/mysql/sql/delete.js +21 -0
  109. package/build/database/drivers/mysql/sql/drop-database.js +6 -0
  110. package/build/database/drivers/mysql/sql/drop-table.js +6 -0
  111. package/build/database/drivers/mysql/sql/insert.js +6 -0
  112. package/build/database/drivers/mysql/sql/update.js +33 -0
  113. package/build/database/drivers/mysql/sql/upsert.js +13 -0
  114. package/build/database/drivers/mysql/structure-sql.js +93 -0
  115. package/build/database/drivers/mysql/table.js +121 -0
  116. package/build/database/drivers/pgsql/column.js +90 -0
  117. package/build/database/drivers/pgsql/columns-index.js +6 -0
  118. package/build/database/drivers/pgsql/foreign-key.js +12 -0
  119. package/build/database/drivers/pgsql/index.js +441 -0
  120. package/build/database/drivers/pgsql/options.js +32 -0
  121. package/build/database/drivers/pgsql/query-parser.js +6 -0
  122. package/build/database/drivers/pgsql/sql/alter-table.js +6 -0
  123. package/build/database/drivers/pgsql/sql/create-database.js +38 -0
  124. package/build/database/drivers/pgsql/sql/create-index.js +6 -0
  125. package/build/database/drivers/pgsql/sql/create-table.js +6 -0
  126. package/build/database/drivers/pgsql/sql/delete.js +21 -0
  127. package/build/database/drivers/pgsql/sql/drop-database.js +6 -0
  128. package/build/database/drivers/pgsql/sql/drop-table.js +6 -0
  129. package/build/database/drivers/pgsql/sql/insert.js +6 -0
  130. package/build/database/drivers/pgsql/sql/update.js +33 -0
  131. package/build/database/drivers/pgsql/sql/upsert.js +14 -0
  132. package/build/database/drivers/pgsql/structure-sql.js +126 -0
  133. package/build/database/drivers/pgsql/table.js +135 -0
  134. package/build/database/drivers/sqlite/base.js +509 -0
  135. package/build/database/drivers/sqlite/column.js +75 -0
  136. package/build/database/drivers/sqlite/columns-index.js +30 -0
  137. package/build/database/drivers/sqlite/connection-sql-js.js +46 -0
  138. package/build/database/drivers/sqlite/foreign-key.js +24 -0
  139. package/build/database/drivers/sqlite/index.js +394 -0
  140. package/build/database/drivers/sqlite/index.native.js +72 -0
  141. package/build/database/drivers/sqlite/index.web.js +99 -0
  142. package/build/database/drivers/sqlite/options.js +32 -0
  143. package/build/database/drivers/sqlite/query-parser.js +6 -0
  144. package/build/database/drivers/sqlite/query.js +35 -0
  145. package/build/database/drivers/sqlite/query.native.js +35 -0
  146. package/build/database/drivers/sqlite/query.web.js +49 -0
  147. package/build/database/drivers/sqlite/sql/alter-table.js +187 -0
  148. package/build/database/drivers/sqlite/sql/create-index.js +6 -0
  149. package/build/database/drivers/sqlite/sql/create-table.js +6 -0
  150. package/build/database/drivers/sqlite/sql/delete.js +26 -0
  151. package/build/database/drivers/sqlite/sql/drop-table.js +6 -0
  152. package/build/database/drivers/sqlite/sql/insert.js +6 -0
  153. package/build/database/drivers/sqlite/sql/update.js +33 -0
  154. package/build/database/drivers/sqlite/sql/upsert.js +14 -0
  155. package/build/database/drivers/sqlite/structure-sql.js +56 -0
  156. package/build/database/drivers/sqlite/table-rebuilder.js +96 -0
  157. package/build/database/drivers/sqlite/table.js +131 -0
  158. package/build/database/drivers/structure-sql/utils.js +35 -0
  159. package/build/database/handler.js +13 -0
  160. package/build/database/initializer-from-require-context.js +101 -0
  161. package/build/database/migration/index.js +438 -0
  162. package/build/database/migrator/files-finder.js +55 -0
  163. package/build/database/migrator/types.js +31 -0
  164. package/build/database/migrator.js +557 -0
  165. package/build/database/pool/async-tracked-multi-connection.js +1164 -0
  166. package/build/database/pool/base-methods-forward.js +52 -0
  167. package/build/database/pool/base.js +380 -0
  168. package/build/database/pool/single-multi-use.js +118 -0
  169. package/build/database/query/alter-table-base.js +104 -0
  170. package/build/database/query/base.js +49 -0
  171. package/build/database/query/create-database-base.js +42 -0
  172. package/build/database/query/create-index-base.js +117 -0
  173. package/build/database/query/create-table-base.js +205 -0
  174. package/build/database/query/delete-base.js +19 -0
  175. package/build/database/query/drop-database-base.js +38 -0
  176. package/build/database/query/drop-table-base.js +58 -0
  177. package/build/database/query/from-base.js +36 -0
  178. package/build/database/query/from-plain.js +16 -0
  179. package/build/database/query/from-table.js +18 -0
  180. package/build/database/query/index.js +533 -0
  181. package/build/database/query/insert-base.js +172 -0
  182. package/build/database/query/join-base.js +43 -0
  183. package/build/database/query/join-object.js +167 -0
  184. package/build/database/query/join-plain.js +18 -0
  185. package/build/database/query/join-tracker.js +93 -0
  186. package/build/database/query/model-class-query.js +1577 -0
  187. package/build/database/query/order-base.js +33 -0
  188. package/build/database/query/order-column.js +77 -0
  189. package/build/database/query/order-plain.js +28 -0
  190. package/build/database/query/preloader/belongs-to.js +267 -0
  191. package/build/database/query/preloader/ensure-model-class-initialized.js +18 -0
  192. package/build/database/query/preloader/has-many.js +316 -0
  193. package/build/database/query/preloader/has-one.js +123 -0
  194. package/build/database/query/preloader/selection.js +152 -0
  195. package/build/database/query/preloader.js +201 -0
  196. package/build/database/query/query-data.js +305 -0
  197. package/build/database/query/select-base.js +30 -0
  198. package/build/database/query/select-plain.js +18 -0
  199. package/build/database/query/select-table-and-column.js +28 -0
  200. package/build/database/query/update-base.js +41 -0
  201. package/build/database/query/upsert-base.js +103 -0
  202. package/build/database/query/where-base.js +38 -0
  203. package/build/database/query/where-combinator.js +31 -0
  204. package/build/database/query/where-hash.js +77 -0
  205. package/build/database/query/where-model-class-hash.js +505 -0
  206. package/build/database/query/where-not.js +23 -0
  207. package/build/database/query/where-plain.js +20 -0
  208. package/build/database/query/with-count.js +219 -0
  209. package/build/database/query-parser/base-query-parser.js +40 -0
  210. package/build/database/query-parser/from-parser.js +49 -0
  211. package/build/database/query-parser/group-parser.js +55 -0
  212. package/build/database/query-parser/joins-parser.js +37 -0
  213. package/build/database/query-parser/limit-parser.js +77 -0
  214. package/build/database/query-parser/options.js +94 -0
  215. package/build/database/query-parser/order-parser.js +45 -0
  216. package/build/database/query-parser/select-parser.js +67 -0
  217. package/build/database/query-parser/where-parser.js +46 -0
  218. package/build/database/record/acts-as-list.js +374 -0
  219. package/build/database/record/attachments/download.js +49 -0
  220. package/build/database/record/attachments/handle.js +188 -0
  221. package/build/database/record/attachments/normalize-input.js +213 -0
  222. package/build/database/record/attachments/storage-drivers/filesystem.js +114 -0
  223. package/build/database/record/attachments/storage-drivers/native.js +146 -0
  224. package/build/database/record/attachments/storage-drivers/s3.js +245 -0
  225. package/build/database/record/attachments/store.js +591 -0
  226. package/build/database/record/index.js +4094 -0
  227. package/build/database/record/instance-relationships/base.js +289 -0
  228. package/build/database/record/instance-relationships/belongs-to.js +84 -0
  229. package/build/database/record/instance-relationships/has-many.js +284 -0
  230. package/build/database/record/instance-relationships/has-one.js +117 -0
  231. package/build/database/record/record-not-found-error.js +3 -0
  232. package/build/database/record/relationships/base.js +195 -0
  233. package/build/database/record/relationships/belongs-to.js +57 -0
  234. package/build/database/record/relationships/has-many.js +46 -0
  235. package/build/database/record/relationships/has-one.js +46 -0
  236. package/build/database/record/state-machine.js +278 -0
  237. package/build/database/record/user-module.js +43 -0
  238. package/build/database/record/validators/base.js +27 -0
  239. package/build/database/record/validators/format.js +50 -0
  240. package/build/database/record/validators/presence.js +24 -0
  241. package/build/database/record/validators/uniqueness.js +124 -0
  242. package/build/database/table-data/index.js +241 -0
  243. package/build/database/table-data/table-column.js +416 -0
  244. package/build/database/table-data/table-foreign-key.js +69 -0
  245. package/build/database/table-data/table-index.js +46 -0
  246. package/build/database/table-data/table-reference.js +13 -0
  247. package/build/database/use-database.js +48 -0
  248. package/build/environment-handlers/base.js +561 -0
  249. package/build/environment-handlers/browser.js +338 -0
  250. package/build/environment-handlers/node/cli/commands/background-jobs-main.js +21 -0
  251. package/build/environment-handlers/node/cli/commands/background-jobs-runner.js +24 -0
  252. package/build/environment-handlers/node/cli/commands/background-jobs-worker.js +47 -0
  253. package/build/environment-handlers/node/cli/commands/beacon.js +21 -0
  254. package/build/environment-handlers/node/cli/commands/cli-command-context.js +31 -0
  255. package/build/environment-handlers/node/cli/commands/console.js +149 -0
  256. package/build/environment-handlers/node/cli/commands/db/schema/dump.js +43 -0
  257. package/build/environment-handlers/node/cli/commands/db/schema/load.js +69 -0
  258. package/build/environment-handlers/node/cli/commands/db/seed.js +79 -0
  259. package/build/environment-handlers/node/cli/commands/destroy/migration.js +47 -0
  260. package/build/environment-handlers/node/cli/commands/generate/base-models.js +396 -0
  261. package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +872 -0
  262. package/build/environment-handlers/node/cli/commands/generate/migration.js +45 -0
  263. package/build/environment-handlers/node/cli/commands/generate/model.js +45 -0
  264. package/build/environment-handlers/node/cli/commands/init.js +68 -0
  265. package/build/environment-handlers/node/cli/commands/routes.js +63 -0
  266. package/build/environment-handlers/node/cli/commands/run-script.js +85 -0
  267. package/build/environment-handlers/node/cli/commands/runner.js +84 -0
  268. package/build/environment-handlers/node/cli/commands/server.js +151 -0
  269. package/build/environment-handlers/node/cli/commands/test.js +118 -0
  270. package/build/environment-handlers/node.js +887 -0
  271. package/build/error-logger.js +30 -0
  272. package/build/frontend-model-controller.js +3491 -0
  273. package/build/frontend-model-resource/base-resource.js +935 -0
  274. package/build/frontend-models/base.js +4004 -0
  275. package/build/frontend-models/clear-pending-debounced-callback.js +16 -0
  276. package/build/frontend-models/event-hook-models.js +49 -0
  277. package/build/frontend-models/model-registry.js +28 -0
  278. package/build/frontend-models/outgoing-event-buffer.js +51 -0
  279. package/build/frontend-models/preloader.js +169 -0
  280. package/build/frontend-models/query.js +2245 -0
  281. package/build/frontend-models/resource-config-validation.js +56 -0
  282. package/build/frontend-models/resource-definition.js +399 -0
  283. package/build/frontend-models/transport-serialization.js +369 -0
  284. package/build/frontend-models/use-created-event.js +21 -0
  285. package/build/frontend-models/use-destroyed-event.js +148 -0
  286. package/build/frontend-models/use-model-class-event.js +164 -0
  287. package/build/frontend-models/use-updated-event.js +152 -0
  288. package/build/frontend-models/websocket-channel.js +494 -0
  289. package/build/frontend-models/websocket-publishers.js +224 -0
  290. package/build/http-client/header.js +17 -0
  291. package/build/http-client/index.js +139 -0
  292. package/build/http-client/request.js +94 -0
  293. package/build/http-client/response.js +151 -0
  294. package/build/http-client/websocket-client.js +27 -0
  295. package/build/http-server/client/index.js +507 -0
  296. package/build/http-server/client/params-to-object.js +152 -0
  297. package/build/http-server/client/request-buffer/form-data-part.js +139 -0
  298. package/build/http-server/client/request-buffer/header.js +19 -0
  299. package/build/http-server/client/request-buffer/index.js +535 -0
  300. package/build/http-server/client/request-parser.js +195 -0
  301. package/build/http-server/client/request-runner.js +321 -0
  302. package/build/http-server/client/request-timing.js +171 -0
  303. package/build/http-server/client/request.js +114 -0
  304. package/build/http-server/client/response.js +251 -0
  305. package/build/http-server/client/uploaded-file/memory-uploaded-file.js +32 -0
  306. package/build/http-server/client/uploaded-file/temporary-uploaded-file.js +32 -0
  307. package/build/http-server/client/uploaded-file/uploaded-file.js +36 -0
  308. package/build/http-server/client/websocket-request.js +147 -0
  309. package/build/http-server/client/websocket-session.js +1755 -0
  310. package/build/http-server/cookie.js +245 -0
  311. package/build/http-server/development-reloader.js +240 -0
  312. package/build/http-server/index.js +561 -0
  313. package/build/http-server/remote-address.js +77 -0
  314. package/build/http-server/server-client.js +222 -0
  315. package/build/http-server/server-lock.js +178 -0
  316. package/build/http-server/websocket-channel-subscribers.js +110 -0
  317. package/build/http-server/websocket-channel.js +137 -0
  318. package/build/http-server/websocket-connection.js +118 -0
  319. package/build/http-server/websocket-event-log-store.js +433 -0
  320. package/build/http-server/websocket-events-host.js +170 -0
  321. package/build/http-server/websocket-events.js +50 -0
  322. package/build/http-server/worker-handler/channel-subscriber-dispatch.js +28 -0
  323. package/build/http-server/worker-handler/in-process.js +155 -0
  324. package/build/http-server/worker-handler/index.js +370 -0
  325. package/build/http-server/worker-handler/worker-script.js +6 -0
  326. package/build/http-server/worker-handler/worker-thread.js +286 -0
  327. package/build/index.js +1 -2
  328. package/build/initializer.js +39 -0
  329. package/build/jobs/mail-delivery.js +22 -0
  330. package/build/logger/base-logger.js +34 -0
  331. package/build/logger/console-logger.js +28 -0
  332. package/build/logger/file-logger.js +36 -0
  333. package/build/logger/outputs/array-output.js +50 -0
  334. package/build/logger/outputs/console-output.js +32 -0
  335. package/build/logger/outputs/file-output.js +55 -0
  336. package/build/logger/outputs/stdout-output.js +64 -0
  337. package/build/logger.js +507 -0
  338. package/build/mailer/backends/smtp.js +197 -0
  339. package/build/mailer/base.js +337 -0
  340. package/build/mailer/delivery.js +70 -0
  341. package/build/mailer/index.js +24 -0
  342. package/build/mailer.js +15 -0
  343. package/build/plugins/sqljs-wasm-route-controller.js +70 -0
  344. package/build/plugins/sqljs-wasm-route.js +71 -0
  345. package/build/record-payload-values.js +83 -0
  346. package/build/routes/app-routes.js +17 -0
  347. package/build/routes/base-route.js +133 -0
  348. package/build/routes/basic-route.js +109 -0
  349. package/build/routes/built-in/debug/controller.js +12 -0
  350. package/build/routes/built-in/errors/controller.js +7 -0
  351. package/build/routes/get-route.js +75 -0
  352. package/build/routes/hooks/frontend-model-command-route-hook.js +100 -0
  353. package/build/routes/index.js +50 -0
  354. package/build/routes/namespace-route.js +51 -0
  355. package/build/routes/plugin-routes.js +141 -0
  356. package/build/routes/post-route.js +74 -0
  357. package/build/routes/resolver.js +535 -0
  358. package/build/routes/resource-route.js +154 -0
  359. package/build/routes/root-route.js +11 -0
  360. package/build/src/authorization/ability.d.ts +24 -23
  361. package/build/src/authorization/ability.d.ts.map +1 -1
  362. package/build/src/authorization/ability.js +14 -13
  363. package/build/src/authorization/base-resource.d.ts +20 -26
  364. package/build/src/authorization/base-resource.d.ts.map +1 -1
  365. package/build/src/authorization/base-resource.js +13 -11
  366. package/build/src/configuration-types.d.ts +21 -2
  367. package/build/src/configuration-types.d.ts.map +1 -1
  368. package/build/src/configuration-types.js +8 -2
  369. package/build/src/database/query/where-combinator.d.ts.map +1 -1
  370. package/build/src/database/query/where-combinator.js +1 -2
  371. package/build/src/database/record/acts-as-list.js +2 -2
  372. package/build/src/database/record/attachments/store.d.ts +1 -1
  373. package/build/src/database/record/attachments/store.d.ts.map +1 -1
  374. package/build/src/database/record/attachments/store.js +2 -2
  375. package/build/src/database/record/index.d.ts +82 -20
  376. package/build/src/database/record/index.d.ts.map +1 -1
  377. package/build/src/database/record/index.js +126 -13
  378. package/build/src/database/record/relationships/base.d.ts +2 -2
  379. package/build/src/database/record/relationships/base.d.ts.map +1 -1
  380. package/build/src/database/record/relationships/base.js +3 -3
  381. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +4 -2
  382. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
  383. package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +59 -36
  384. package/build/src/frontend-model-controller.d.ts +6 -6
  385. package/build/src/frontend-model-controller.d.ts.map +1 -1
  386. package/build/src/frontend-model-controller.js +4 -4
  387. package/build/src/frontend-model-resource/base-resource.d.ts +18 -17
  388. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  389. package/build/src/frontend-model-resource/base-resource.js +22 -10
  390. package/build/src/frontend-models/base.d.ts +19 -12
  391. package/build/src/frontend-models/base.d.ts.map +1 -1
  392. package/build/src/frontend-models/base.js +79 -48
  393. package/build/src/frontend-models/preloader.d.ts +6 -6
  394. package/build/src/frontend-models/preloader.d.ts.map +1 -1
  395. package/build/src/frontend-models/preloader.js +5 -5
  396. package/build/src/frontend-models/query.d.ts.map +1 -1
  397. package/build/src/frontend-models/query.js +1 -4
  398. package/build/src/utils/ransack.d.ts.map +1 -1
  399. package/build/src/utils/ransack.js +1 -2
  400. package/build/templates/configuration.js +61 -0
  401. package/build/templates/generate-migration.js +11 -0
  402. package/build/templates/generate-model.js +6 -0
  403. package/build/templates/routes.js +11 -0
  404. package/build/testing/base-expect.js +17 -0
  405. package/build/testing/browser-frontend-model-event-hook-scenarios.js +520 -0
  406. package/build/testing/browser-test-app.js +32 -0
  407. package/build/testing/expect-to-change.js +55 -0
  408. package/build/testing/expect-utils.js +269 -0
  409. package/build/testing/expect.js +763 -0
  410. package/build/testing/request-client.js +90 -0
  411. package/build/testing/test-files-finder.js +364 -0
  412. package/build/testing/test-filter-parser.js +198 -0
  413. package/build/testing/test-runner.js +1168 -0
  414. package/build/testing/test-suite-splitter.js +177 -0
  415. package/build/testing/test.js +370 -0
  416. package/build/utils/backtrace-cleaner-node.js +87 -0
  417. package/build/utils/backtrace-cleaner.js +266 -0
  418. package/build/utils/ensure-error.js +15 -0
  419. package/build/utils/event-emitter.js +8 -0
  420. package/build/utils/file-exists.js +18 -0
  421. package/build/utils/format-value.js +101 -0
  422. package/build/utils/model-scope.js +56 -0
  423. package/build/utils/nest-callbacks.js +22 -0
  424. package/build/utils/plain-object.js +14 -0
  425. package/build/utils/ransack.js +859 -0
  426. package/build/utils/rest-args-error.js +14 -0
  427. package/build/utils/singularize-model-name.js +18 -0
  428. package/build/utils/split-sql-statements.js +88 -0
  429. package/build/utils/to-import-specifier.js +53 -0
  430. package/build/utils/with-tracked-stack-async-hooks.js +103 -0
  431. package/build/utils/with-tracked-stack.js +38 -0
  432. package/build/velocious-error.js +34 -0
  433. package/index.js +1 -0
  434. package/package.json +10 -4
  435. package/scripts/clean-build.js +8 -0
  436. package/scripts/ensure-bin-executable.js +13 -0
  437. package/scripts/run-tests.js +37 -0
  438. package/scripts/test-browser.js +486 -0
  439. package/src/application.js +229 -0
  440. package/src/authorization/ability.js +329 -0
  441. package/src/authorization/base-resource.js +143 -0
  442. package/src/background-jobs/client.js +50 -0
  443. package/src/background-jobs/cron-expression.js +277 -0
  444. package/src/background-jobs/forked-runner-child.js +86 -0
  445. package/src/background-jobs/job-record.js +13 -0
  446. package/src/background-jobs/job-registry.js +92 -0
  447. package/src/background-jobs/job-runner.js +107 -0
  448. package/src/background-jobs/job.js +77 -0
  449. package/src/background-jobs/json-socket.js +78 -0
  450. package/src/background-jobs/main.js +926 -0
  451. package/src/background-jobs/normalize-error.js +26 -0
  452. package/src/background-jobs/scheduler.js +274 -0
  453. package/src/background-jobs/socket-request.js +68 -0
  454. package/src/background-jobs/status-reporter.js +101 -0
  455. package/src/background-jobs/store.js +994 -0
  456. package/src/background-jobs/types.js +70 -0
  457. package/src/background-jobs/web/authorization.js +89 -0
  458. package/src/background-jobs/web/controller.js +280 -0
  459. package/src/background-jobs/web/index.js +57 -0
  460. package/src/background-jobs/web/path-matcher.js +74 -0
  461. package/src/background-jobs/web/registry.js +49 -0
  462. package/src/background-jobs/worker.js +683 -0
  463. package/src/beacon/client.js +330 -0
  464. package/src/beacon/in-process-broker.js +71 -0
  465. package/src/beacon/in-process-client.js +139 -0
  466. package/src/beacon/server.js +148 -0
  467. package/src/beacon/types.js +55 -0
  468. package/src/cli/base-command.js +67 -0
  469. package/src/cli/browser-cli.js +45 -0
  470. package/src/cli/commands/background-jobs-main.js +7 -0
  471. package/src/cli/commands/background-jobs-runner.js +7 -0
  472. package/src/cli/commands/background-jobs-worker.js +7 -0
  473. package/src/cli/commands/beacon.js +7 -0
  474. package/src/cli/commands/console.js +12 -0
  475. package/src/cli/commands/db/base-command.js +82 -0
  476. package/src/cli/commands/db/create.js +64 -0
  477. package/src/cli/commands/db/drop.js +75 -0
  478. package/src/cli/commands/db/migrate.js +17 -0
  479. package/src/cli/commands/db/reset.js +22 -0
  480. package/src/cli/commands/db/rollback.js +15 -0
  481. package/src/cli/commands/db/schema/dump.js +12 -0
  482. package/src/cli/commands/db/schema/load.js +12 -0
  483. package/src/cli/commands/db/seed.js +12 -0
  484. package/src/cli/commands/db/tenants/check.js +38 -0
  485. package/src/cli/commands/db/tenants/create.js +33 -0
  486. package/src/cli/commands/db/tenants/migrate.js +49 -0
  487. package/src/cli/commands/destroy/migration.js +7 -0
  488. package/src/cli/commands/generate/base-models.js +7 -0
  489. package/src/cli/commands/generate/frontend-models.js +12 -0
  490. package/src/cli/commands/generate/migration.js +7 -0
  491. package/src/cli/commands/generate/model.js +7 -0
  492. package/src/cli/commands/init.js +11 -0
  493. package/src/cli/commands/routes.js +7 -0
  494. package/src/cli/commands/run-script.js +12 -0
  495. package/src/cli/commands/runner.js +12 -0
  496. package/src/cli/commands/server.js +7 -0
  497. package/src/cli/commands/test.js +9 -0
  498. package/src/cli/index.js +152 -0
  499. package/src/cli/tenant-database-command-helper.js +198 -0
  500. package/src/cli/use-browser-cli.js +30 -0
  501. package/src/configuration-resolver.js +65 -0
  502. package/src/configuration-types.js +429 -0
  503. package/src/configuration.js +2590 -0
  504. package/src/controller.js +421 -0
  505. package/src/current-configuration.js +31 -0
  506. package/src/current.js +80 -0
  507. package/src/database/annotations-async-hooks.js +47 -0
  508. package/src/database/annotations.js +40 -0
  509. package/src/database/drivers/base-column.js +182 -0
  510. package/src/database/drivers/base-columns-index.js +81 -0
  511. package/src/database/drivers/base-foreign-key.js +104 -0
  512. package/src/database/drivers/base-table.js +156 -0
  513. package/src/database/drivers/base.js +1609 -0
  514. package/src/database/drivers/mssql/column.js +74 -0
  515. package/src/database/drivers/mssql/columns-index.js +6 -0
  516. package/src/database/drivers/mssql/connect-connection.js +16 -0
  517. package/src/database/drivers/mssql/foreign-key.js +12 -0
  518. package/src/database/drivers/mssql/index.js +590 -0
  519. package/src/database/drivers/mssql/options.js +79 -0
  520. package/src/database/drivers/mssql/query-parser.js +6 -0
  521. package/src/database/drivers/mssql/sql/alter-table.js +4 -0
  522. package/src/database/drivers/mssql/sql/create-database.js +36 -0
  523. package/src/database/drivers/mssql/sql/create-index.js +4 -0
  524. package/src/database/drivers/mssql/sql/create-table.js +4 -0
  525. package/src/database/drivers/mssql/sql/delete.js +19 -0
  526. package/src/database/drivers/mssql/sql/drop-database.js +36 -0
  527. package/src/database/drivers/mssql/sql/drop-table.js +4 -0
  528. package/src/database/drivers/mssql/sql/insert.js +4 -0
  529. package/src/database/drivers/mssql/sql/update.js +31 -0
  530. package/src/database/drivers/mssql/sql/upsert.js +23 -0
  531. package/src/database/drivers/mssql/structure-sql.js +120 -0
  532. package/src/database/drivers/mssql/table.js +145 -0
  533. package/src/database/drivers/mysql/column.js +112 -0
  534. package/src/database/drivers/mysql/columns-index.js +22 -0
  535. package/src/database/drivers/mysql/foreign-key.js +12 -0
  536. package/src/database/drivers/mysql/index.js +473 -0
  537. package/src/database/drivers/mysql/options.js +34 -0
  538. package/src/database/drivers/mysql/query-parser.js +6 -0
  539. package/src/database/drivers/mysql/query.js +37 -0
  540. package/src/database/drivers/mysql/sql/alter-table.js +6 -0
  541. package/src/database/drivers/mysql/sql/create-database.js +39 -0
  542. package/src/database/drivers/mysql/sql/create-index.js +6 -0
  543. package/src/database/drivers/mysql/sql/create-table.js +6 -0
  544. package/src/database/drivers/mysql/sql/delete.js +21 -0
  545. package/src/database/drivers/mysql/sql/drop-database.js +6 -0
  546. package/src/database/drivers/mysql/sql/drop-table.js +6 -0
  547. package/src/database/drivers/mysql/sql/insert.js +6 -0
  548. package/src/database/drivers/mysql/sql/update.js +33 -0
  549. package/src/database/drivers/mysql/sql/upsert.js +13 -0
  550. package/src/database/drivers/mysql/structure-sql.js +93 -0
  551. package/src/database/drivers/mysql/table.js +121 -0
  552. package/src/database/drivers/pgsql/column.js +90 -0
  553. package/src/database/drivers/pgsql/columns-index.js +6 -0
  554. package/src/database/drivers/pgsql/foreign-key.js +12 -0
  555. package/src/database/drivers/pgsql/index.js +441 -0
  556. package/src/database/drivers/pgsql/options.js +32 -0
  557. package/src/database/drivers/pgsql/query-parser.js +6 -0
  558. package/src/database/drivers/pgsql/sql/alter-table.js +6 -0
  559. package/src/database/drivers/pgsql/sql/create-database.js +38 -0
  560. package/src/database/drivers/pgsql/sql/create-index.js +6 -0
  561. package/src/database/drivers/pgsql/sql/create-table.js +6 -0
  562. package/src/database/drivers/pgsql/sql/delete.js +21 -0
  563. package/src/database/drivers/pgsql/sql/drop-database.js +6 -0
  564. package/src/database/drivers/pgsql/sql/drop-table.js +6 -0
  565. package/src/database/drivers/pgsql/sql/insert.js +6 -0
  566. package/src/database/drivers/pgsql/sql/update.js +33 -0
  567. package/src/database/drivers/pgsql/sql/upsert.js +14 -0
  568. package/src/database/drivers/pgsql/structure-sql.js +126 -0
  569. package/src/database/drivers/pgsql/table.js +135 -0
  570. package/src/database/drivers/sqlite/base.js +509 -0
  571. package/src/database/drivers/sqlite/column.js +75 -0
  572. package/src/database/drivers/sqlite/columns-index.js +30 -0
  573. package/src/database/drivers/sqlite/connection-sql-js.js +46 -0
  574. package/src/database/drivers/sqlite/foreign-key.js +24 -0
  575. package/src/database/drivers/sqlite/index.js +394 -0
  576. package/src/database/drivers/sqlite/index.native.js +72 -0
  577. package/src/database/drivers/sqlite/index.web.js +99 -0
  578. package/src/database/drivers/sqlite/options.js +32 -0
  579. package/src/database/drivers/sqlite/query-parser.js +6 -0
  580. package/src/database/drivers/sqlite/query.js +35 -0
  581. package/src/database/drivers/sqlite/query.native.js +35 -0
  582. package/src/database/drivers/sqlite/query.web.js +49 -0
  583. package/src/database/drivers/sqlite/sql/alter-table.js +187 -0
  584. package/src/database/drivers/sqlite/sql/create-index.js +6 -0
  585. package/src/database/drivers/sqlite/sql/create-table.js +6 -0
  586. package/src/database/drivers/sqlite/sql/delete.js +26 -0
  587. package/src/database/drivers/sqlite/sql/drop-table.js +6 -0
  588. package/src/database/drivers/sqlite/sql/insert.js +6 -0
  589. package/src/database/drivers/sqlite/sql/update.js +33 -0
  590. package/src/database/drivers/sqlite/sql/upsert.js +14 -0
  591. package/src/database/drivers/sqlite/structure-sql.js +56 -0
  592. package/src/database/drivers/sqlite/table-rebuilder.js +96 -0
  593. package/src/database/drivers/sqlite/table.js +131 -0
  594. package/src/database/drivers/structure-sql/utils.js +35 -0
  595. package/src/database/handler.js +13 -0
  596. package/src/database/initializer-from-require-context.js +101 -0
  597. package/src/database/migration/index.js +438 -0
  598. package/src/database/migrator/files-finder.js +55 -0
  599. package/src/database/migrator/types.js +31 -0
  600. package/src/database/migrator.js +557 -0
  601. package/src/database/pool/async-tracked-multi-connection.js +1164 -0
  602. package/src/database/pool/base-methods-forward.js +52 -0
  603. package/src/database/pool/base.js +380 -0
  604. package/src/database/pool/single-multi-use.js +118 -0
  605. package/src/database/query/alter-table-base.js +104 -0
  606. package/src/database/query/base.js +49 -0
  607. package/src/database/query/create-database-base.js +42 -0
  608. package/src/database/query/create-index-base.js +117 -0
  609. package/src/database/query/create-table-base.js +205 -0
  610. package/src/database/query/delete-base.js +19 -0
  611. package/src/database/query/drop-database-base.js +38 -0
  612. package/src/database/query/drop-table-base.js +58 -0
  613. package/src/database/query/from-base.js +36 -0
  614. package/src/database/query/from-plain.js +16 -0
  615. package/src/database/query/from-table.js +18 -0
  616. package/src/database/query/index.js +533 -0
  617. package/src/database/query/insert-base.js +172 -0
  618. package/src/database/query/join-base.js +43 -0
  619. package/src/database/query/join-object.js +167 -0
  620. package/src/database/query/join-plain.js +18 -0
  621. package/src/database/query/join-tracker.js +93 -0
  622. package/src/database/query/model-class-query.js +1577 -0
  623. package/src/database/query/order-base.js +33 -0
  624. package/src/database/query/order-column.js +77 -0
  625. package/src/database/query/order-plain.js +28 -0
  626. package/src/database/query/preloader/belongs-to.js +267 -0
  627. package/src/database/query/preloader/ensure-model-class-initialized.js +18 -0
  628. package/src/database/query/preloader/has-many.js +316 -0
  629. package/src/database/query/preloader/has-one.js +123 -0
  630. package/src/database/query/preloader/selection.js +152 -0
  631. package/src/database/query/preloader.js +201 -0
  632. package/src/database/query/query-data.js +305 -0
  633. package/src/database/query/select-base.js +30 -0
  634. package/src/database/query/select-plain.js +18 -0
  635. package/src/database/query/select-table-and-column.js +28 -0
  636. package/src/database/query/update-base.js +41 -0
  637. package/src/database/query/upsert-base.js +103 -0
  638. package/src/database/query/where-base.js +38 -0
  639. package/src/database/query/where-combinator.js +31 -0
  640. package/src/database/query/where-hash.js +77 -0
  641. package/src/database/query/where-model-class-hash.js +505 -0
  642. package/src/database/query/where-not.js +23 -0
  643. package/src/database/query/where-plain.js +20 -0
  644. package/src/database/query/with-count.js +219 -0
  645. package/src/database/query-parser/base-query-parser.js +40 -0
  646. package/src/database/query-parser/from-parser.js +49 -0
  647. package/src/database/query-parser/group-parser.js +55 -0
  648. package/src/database/query-parser/joins-parser.js +37 -0
  649. package/src/database/query-parser/limit-parser.js +77 -0
  650. package/src/database/query-parser/options.js +94 -0
  651. package/src/database/query-parser/order-parser.js +45 -0
  652. package/src/database/query-parser/select-parser.js +67 -0
  653. package/src/database/query-parser/where-parser.js +46 -0
  654. package/src/database/record/acts-as-list.js +374 -0
  655. package/src/database/record/attachments/download.js +49 -0
  656. package/src/database/record/attachments/handle.js +188 -0
  657. package/src/database/record/attachments/normalize-input.js +213 -0
  658. package/src/database/record/attachments/storage-drivers/filesystem.js +114 -0
  659. package/src/database/record/attachments/storage-drivers/native.js +146 -0
  660. package/src/database/record/attachments/storage-drivers/s3.js +245 -0
  661. package/src/database/record/attachments/store.js +591 -0
  662. package/src/database/record/index.js +4094 -0
  663. package/src/database/record/instance-relationships/base.js +289 -0
  664. package/src/database/record/instance-relationships/belongs-to.js +84 -0
  665. package/src/database/record/instance-relationships/has-many.js +284 -0
  666. package/src/database/record/instance-relationships/has-one.js +117 -0
  667. package/src/database/record/record-not-found-error.js +3 -0
  668. package/src/database/record/relationships/base.js +195 -0
  669. package/src/database/record/relationships/belongs-to.js +57 -0
  670. package/src/database/record/relationships/has-many.js +46 -0
  671. package/src/database/record/relationships/has-one.js +46 -0
  672. package/src/database/record/state-machine.js +278 -0
  673. package/src/database/record/user-module.js +43 -0
  674. package/src/database/record/validators/base.js +27 -0
  675. package/src/database/record/validators/format.js +50 -0
  676. package/src/database/record/validators/presence.js +24 -0
  677. package/src/database/record/validators/uniqueness.js +124 -0
  678. package/src/database/table-data/index.js +241 -0
  679. package/src/database/table-data/table-column.js +416 -0
  680. package/src/database/table-data/table-foreign-key.js +69 -0
  681. package/src/database/table-data/table-index.js +46 -0
  682. package/src/database/table-data/table-reference.js +13 -0
  683. package/src/database/use-database.js +48 -0
  684. package/src/environment-handlers/base.js +561 -0
  685. package/src/environment-handlers/browser.js +338 -0
  686. package/src/environment-handlers/node/cli/commands/background-jobs-main.js +21 -0
  687. package/src/environment-handlers/node/cli/commands/background-jobs-runner.js +24 -0
  688. package/src/environment-handlers/node/cli/commands/background-jobs-worker.js +47 -0
  689. package/src/environment-handlers/node/cli/commands/beacon.js +21 -0
  690. package/src/environment-handlers/node/cli/commands/cli-command-context.js +31 -0
  691. package/src/environment-handlers/node/cli/commands/console.js +149 -0
  692. package/src/environment-handlers/node/cli/commands/db/schema/dump.js +43 -0
  693. package/src/environment-handlers/node/cli/commands/db/schema/load.js +69 -0
  694. package/src/environment-handlers/node/cli/commands/db/seed.js +79 -0
  695. package/src/environment-handlers/node/cli/commands/destroy/migration.js +47 -0
  696. package/src/environment-handlers/node/cli/commands/generate/base-models.js +396 -0
  697. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +872 -0
  698. package/src/environment-handlers/node/cli/commands/generate/migration.js +45 -0
  699. package/src/environment-handlers/node/cli/commands/generate/model.js +45 -0
  700. package/src/environment-handlers/node/cli/commands/init.js +68 -0
  701. package/src/environment-handlers/node/cli/commands/routes.js +63 -0
  702. package/src/environment-handlers/node/cli/commands/run-script.js +85 -0
  703. package/src/environment-handlers/node/cli/commands/runner.js +84 -0
  704. package/src/environment-handlers/node/cli/commands/server.js +151 -0
  705. package/src/environment-handlers/node/cli/commands/test.js +118 -0
  706. package/src/environment-handlers/node.js +887 -0
  707. package/src/error-logger.js +30 -0
  708. package/src/frontend-model-controller.js +3491 -0
  709. package/src/frontend-model-resource/base-resource.js +935 -0
  710. package/src/frontend-models/base.js +4004 -0
  711. package/src/frontend-models/clear-pending-debounced-callback.js +16 -0
  712. package/src/frontend-models/event-hook-models.js +49 -0
  713. package/src/frontend-models/model-registry.js +28 -0
  714. package/src/frontend-models/outgoing-event-buffer.js +51 -0
  715. package/src/frontend-models/preloader.js +169 -0
  716. package/src/frontend-models/query.js +2245 -0
  717. package/src/frontend-models/resource-config-validation.js +56 -0
  718. package/src/frontend-models/resource-definition.js +399 -0
  719. package/src/frontend-models/transport-serialization.js +369 -0
  720. package/src/frontend-models/use-created-event.js +21 -0
  721. package/src/frontend-models/use-destroyed-event.js +148 -0
  722. package/src/frontend-models/use-model-class-event.js +164 -0
  723. package/src/frontend-models/use-updated-event.js +152 -0
  724. package/src/frontend-models/websocket-channel.js +494 -0
  725. package/src/frontend-models/websocket-publishers.js +224 -0
  726. package/src/http-client/header.js +17 -0
  727. package/src/http-client/index.js +139 -0
  728. package/src/http-client/request.js +94 -0
  729. package/src/http-client/response.js +151 -0
  730. package/src/http-client/websocket-client.js +27 -0
  731. package/src/http-server/client/index.js +507 -0
  732. package/src/http-server/client/params-to-object.js +152 -0
  733. package/src/http-server/client/request-buffer/form-data-part.js +139 -0
  734. package/src/http-server/client/request-buffer/header.js +19 -0
  735. package/src/http-server/client/request-buffer/index.js +535 -0
  736. package/src/http-server/client/request-parser.js +195 -0
  737. package/src/http-server/client/request-runner.js +321 -0
  738. package/src/http-server/client/request-timing.js +171 -0
  739. package/src/http-server/client/request.js +114 -0
  740. package/src/http-server/client/response.js +251 -0
  741. package/src/http-server/client/uploaded-file/memory-uploaded-file.js +32 -0
  742. package/src/http-server/client/uploaded-file/temporary-uploaded-file.js +32 -0
  743. package/src/http-server/client/uploaded-file/uploaded-file.js +36 -0
  744. package/src/http-server/client/websocket-request.js +147 -0
  745. package/src/http-server/client/websocket-session.js +1755 -0
  746. package/src/http-server/cookie.js +245 -0
  747. package/src/http-server/development-reloader.js +240 -0
  748. package/src/http-server/index.js +561 -0
  749. package/src/http-server/remote-address.js +77 -0
  750. package/src/http-server/server-client.js +222 -0
  751. package/src/http-server/server-lock.js +178 -0
  752. package/src/http-server/websocket-channel-subscribers.js +110 -0
  753. package/src/http-server/websocket-channel.js +137 -0
  754. package/src/http-server/websocket-connection.js +118 -0
  755. package/src/http-server/websocket-event-log-store.js +433 -0
  756. package/src/http-server/websocket-events-host.js +170 -0
  757. package/src/http-server/websocket-events.js +50 -0
  758. package/src/http-server/worker-handler/channel-subscriber-dispatch.js +28 -0
  759. package/src/http-server/worker-handler/in-process.js +155 -0
  760. package/src/http-server/worker-handler/index.js +370 -0
  761. package/src/http-server/worker-handler/worker-script.js +6 -0
  762. package/src/http-server/worker-handler/worker-thread.js +286 -0
  763. package/src/initializer.js +39 -0
  764. package/src/jobs/.gitkeep +1 -0
  765. package/src/jobs/mail-delivery.js +22 -0
  766. package/src/logger/base-logger.js +34 -0
  767. package/src/logger/console-logger.js +28 -0
  768. package/src/logger/file-logger.js +36 -0
  769. package/src/logger/outputs/array-output.js +50 -0
  770. package/src/logger/outputs/console-output.js +32 -0
  771. package/src/logger/outputs/file-output.js +55 -0
  772. package/src/logger/outputs/stdout-output.js +64 -0
  773. package/src/logger.js +507 -0
  774. package/src/mailer/backends/smtp.js +197 -0
  775. package/src/mailer/base.js +337 -0
  776. package/src/mailer/delivery.js +70 -0
  777. package/src/mailer/index.js +24 -0
  778. package/src/mailer.js +15 -0
  779. package/src/plugins/sqljs-wasm-route-controller.js +70 -0
  780. package/src/plugins/sqljs-wasm-route.js +71 -0
  781. package/src/record-payload-values.js +83 -0
  782. package/src/routes/app-routes.js +17 -0
  783. package/src/routes/base-route.js +133 -0
  784. package/src/routes/basic-route.js +109 -0
  785. package/src/routes/built-in/debug/controller.js +12 -0
  786. package/src/routes/built-in/errors/controller.js +7 -0
  787. package/src/routes/built-in/errors/not-found.ejs +1 -0
  788. package/src/routes/get-route.js +75 -0
  789. package/src/routes/hooks/frontend-model-command-route-hook.js +100 -0
  790. package/src/routes/index.js +50 -0
  791. package/src/routes/namespace-route.js +51 -0
  792. package/src/routes/plugin-routes.js +141 -0
  793. package/src/routes/post-route.js +74 -0
  794. package/src/routes/resolver.js +535 -0
  795. package/src/routes/resource-route.js +154 -0
  796. package/src/routes/root-route.js +11 -0
  797. package/src/templates/configuration.js +61 -0
  798. package/src/templates/generate-migration.js +11 -0
  799. package/src/templates/generate-model.js +6 -0
  800. package/src/templates/routes.js +11 -0
  801. package/src/testing/base-expect.js +17 -0
  802. package/src/testing/browser-frontend-model-event-hook-scenarios.js +520 -0
  803. package/src/testing/browser-test-app.js +32 -0
  804. package/src/testing/expect-to-change.js +55 -0
  805. package/src/testing/expect-utils.js +269 -0
  806. package/src/testing/expect.js +763 -0
  807. package/src/testing/request-client.js +90 -0
  808. package/src/testing/test-files-finder.js +364 -0
  809. package/src/testing/test-filter-parser.js +198 -0
  810. package/src/testing/test-runner.js +1168 -0
  811. package/src/testing/test-suite-splitter.js +177 -0
  812. package/src/testing/test.js +370 -0
  813. package/src/types/external-modules.d.ts +57 -0
  814. package/src/utils/backtrace-cleaner-node.js +87 -0
  815. package/src/utils/backtrace-cleaner.js +266 -0
  816. package/src/utils/ensure-error.js +15 -0
  817. package/src/utils/event-emitter.js +8 -0
  818. package/src/utils/file-exists.js +18 -0
  819. package/src/utils/format-value.js +101 -0
  820. package/src/utils/model-scope.js +56 -0
  821. package/src/utils/nest-callbacks.js +22 -0
  822. package/src/utils/plain-object.js +14 -0
  823. package/src/utils/ransack.js +859 -0
  824. package/src/utils/rest-args-error.js +14 -0
  825. package/src/utils/singularize-model-name.js +18 -0
  826. package/src/utils/split-sql-statements.js +88 -0
  827. package/src/utils/to-import-specifier.js +53 -0
  828. package/src/utils/with-tracked-stack-async-hooks.js +103 -0
  829. package/src/utils/with-tracked-stack.js +38 -0
  830. package/src/velocious-error.js +34 -0
  831. package/tsconfig.json +16 -0
@@ -0,0 +1,994 @@
1
+ // @ts-check
2
+
3
+ import {randomUUID} from "crypto"
4
+ import Logger from "../logger.js"
5
+ import TableData from "../database/table-data/index.js"
6
+ import BackgroundJobRecord from "./job-record.js"
7
+ import normalizeBackgroundJobError from "./normalize-error.js"
8
+
9
+ const MIGRATIONS_TABLE = "velocious_internal_migrations"
10
+ const MIGRATION_SCOPE = "background_jobs"
11
+ const MIGRATION_VERSION = "20250215000000"
12
+ const EXECUTION_MODE_BACKFILL_MIGRATION_VERSION = "20260607131010"
13
+ const JOBS_TABLE = "background_jobs"
14
+ const DEFAULT_MAX_RETRIES = 10
15
+ const ORPHANED_AFTER_MS = 2 * 60 * 60 * 1000
16
+ /**
17
+ * Execution modes.
18
+ @type {import("./types.js").BackgroundJobExecutionMode[]} */
19
+ const EXECUTION_MODES = ["inline", "forked", "spawned"]
20
+ const DEFAULT_EXECUTION_MODE = "forked"
21
+
22
+ /**
23
+ * Columns the dashboard is allowed to sort job listings by, mapped to their
24
+ * database column names. Restricting to this set keeps the sort parameter
25
+ * (which originates from untrusted query strings) from reaching raw SQL.
26
+ * @type {Record<string, string>}
27
+ */
28
+ const SORTABLE_COLUMNS = {
29
+ attempts: "attempts",
30
+ completedAtMs: "completed_at_ms",
31
+ createdAtMs: "created_at_ms",
32
+ failedAtMs: "failed_at_ms",
33
+ handedOffAtMs: "handed_off_at_ms",
34
+ scheduledAtMs: "scheduled_at_ms"
35
+ }
36
+
37
+ export default class BackgroundJobsStore {
38
+ /**
39
+ * Runs constructor.
40
+ * @param {object} args - Options.
41
+ * @param {import("../configuration.js").default} args.configuration - Configuration.
42
+ * @param {string} [args.databaseIdentifier] - Database identifier.
43
+ */
44
+ constructor({configuration, databaseIdentifier}) {
45
+ this.configuration = configuration
46
+ this.databaseIdentifier = databaseIdentifier
47
+ this.logger = new Logger(this)
48
+ this._readyPromise = null
49
+ }
50
+
51
+ /**
52
+ * Runs get database identifier.
53
+ * @returns {string} - Database identifier.
54
+ */
55
+ getDatabaseIdentifier() {
56
+ if (this.databaseIdentifier) return this.databaseIdentifier
57
+
58
+ return this.configuration.getBackgroundJobsConfig().databaseIdentifier
59
+ }
60
+
61
+ /**
62
+ * Runs ensure ready.
63
+ * @returns {Promise<void>} - Resolves when ready.
64
+ */
65
+ async ensureReady() {
66
+ if (this._readyPromise) return await this._readyPromise
67
+
68
+ this._readyPromise = (async () => {
69
+ this.configuration.setCurrent()
70
+ await this._ensureSchema()
71
+ await this._initializeModel()
72
+ })()
73
+
74
+ try {
75
+ await this._readyPromise
76
+ } finally {
77
+ this._readyPromise = null
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Runs enqueue.
83
+ * @param {object} args - Options.
84
+ * @param {string} args.jobName - Job name.
85
+ * @param {Array<?>} args.args - Arguments.
86
+ * @param {import("./types.js").BackgroundJobOptions} [args.options] - Options.
87
+ * @returns {Promise<string>} - Job id.
88
+ */
89
+ async enqueue({jobName, args, options}) {
90
+ await this.ensureReady()
91
+
92
+ const jobId = randomUUID()
93
+ const now = Date.now()
94
+ const executionMode = this._normalizeExecutionMode(options)
95
+ const maxRetries = this._normalizeMaxRetries(options?.maxRetries)
96
+ const argsJson = JSON.stringify(args || [])
97
+
98
+ await this._withDb(async (db) => {
99
+ await db.insert({
100
+ tableName: JOBS_TABLE,
101
+ data: {
102
+ id: jobId,
103
+ job_name: jobName,
104
+ args_json: argsJson,
105
+ forked: executionMode !== "inline",
106
+ execution_mode: executionMode,
107
+ max_retries: maxRetries,
108
+ attempts: 0,
109
+ status: "queued",
110
+ scheduled_at_ms: now,
111
+ created_at_ms: now
112
+ }
113
+ })
114
+ })
115
+
116
+ return jobId
117
+ }
118
+
119
+ /**
120
+ * Runs next available job.
121
+ * @param {object} [args] - Options.
122
+ * @param {boolean} [args.forked] - Compatibility filter for non-inline vs inline jobs.
123
+ * @param {import("./types.js").BackgroundJobExecutionMode | import("./types.js").BackgroundJobExecutionMode[]} [args.executionMode] - Execution mode or modes to match.
124
+ * @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Next job.
125
+ */
126
+ async nextAvailableJob(args = {}) {
127
+ await this.ensureReady()
128
+
129
+ return await this._withDb(async (db) => {
130
+ return await this._nextQueuedJob({
131
+ db,
132
+ scheduledAtOperator: "<=",
133
+ forked: args.forked,
134
+ executionMode: args.executionMode
135
+ })
136
+ })
137
+ }
138
+
139
+ /**
140
+ * Returns the soonest future-scheduled queued job (one whose
141
+ * `scheduled_at_ms` is in the future), or null when there are no
142
+ * future-scheduled jobs. Used by the event-driven dispatcher to arm a
143
+ * `setTimeout` for the exact moment the next scheduled job becomes
144
+ * eligible, replacing the legacy 1-second polling loop.
145
+ * @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Soonest future-scheduled job, or null.
146
+ */
147
+ async nextScheduledJob() {
148
+ await this.ensureReady()
149
+
150
+ return await this._withDb(async (db) => {
151
+ return await this._nextQueuedJob({db, scheduledAtOperator: ">"})
152
+ })
153
+ }
154
+
155
+ /**
156
+ * Runs next queued job.
157
+ * @param {object} args - Options.
158
+ * @param {import("../database/drivers/base.js").default} args.db - Database connection.
159
+ * @param {"<=" | ">"} args.scheduledAtOperator - Scheduled timestamp operator.
160
+ * @param {boolean} [args.forked] - Compatibility filter for non-inline vs inline jobs.
161
+ * @param {import("./types.js").BackgroundJobExecutionMode | import("./types.js").BackgroundJobExecutionMode[]} [args.executionMode] - Execution mode or modes to match.
162
+ * @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Next matching queued job.
163
+ */
164
+ async _nextQueuedJob({db, scheduledAtOperator, forked, executionMode}) {
165
+ const now = Date.now()
166
+ let query = db
167
+ .newQuery()
168
+ .from(JOBS_TABLE)
169
+ .where({status: "queued"})
170
+ .where(`scheduled_at_ms ${scheduledAtOperator} ${db.quote(now)}`)
171
+
172
+ if (typeof forked === "boolean") {
173
+ query = query.where({forked})
174
+ }
175
+ if (executionMode) {
176
+ const executionModes = Array.isArray(executionMode) ? executionMode : [executionMode]
177
+
178
+ query = query.where({execution_mode: executionModes})
179
+ }
180
+
181
+ query = query
182
+ .order("scheduled_at_ms ASC")
183
+ .order("created_at_ms ASC")
184
+ .limit(1)
185
+
186
+ const rows = await query.results()
187
+ const row = rows[0]
188
+
189
+ if (!row) return null
190
+
191
+ return this._normalizeJobRow(row)
192
+ }
193
+
194
+ /**
195
+ * Runs get job.
196
+ * @param {string} jobId - Job id.
197
+ * @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Job row.
198
+ */
199
+ async getJob(jobId) {
200
+ await this.ensureReady()
201
+
202
+ return await this._withDb(async (db) => {
203
+ const query = db
204
+ .newQuery()
205
+ .from(JOBS_TABLE)
206
+ .where({id: jobId})
207
+ .limit(1)
208
+
209
+ const rows = await query.results()
210
+ const row = rows[0]
211
+
212
+ if (!row) return null
213
+
214
+ return this._normalizeJobRow(row)
215
+ })
216
+ }
217
+
218
+ /**
219
+ * Counts jobs grouped by status. Used by the dashboard overview.
220
+ * @returns {Promise<Record<string, number>>} - Counts keyed by status.
221
+ */
222
+ async countsByStatus() {
223
+ await this.ensureReady()
224
+
225
+ return await this._withDb(async (db) => {
226
+ const rows = await db
227
+ .newQuery()
228
+ .from(JOBS_TABLE)
229
+ .select("status")
230
+ .select("COUNT(*) AS count")
231
+ .group("status")
232
+ .results()
233
+
234
+ /**
235
+ * Counts.
236
+ @type {Record<string, number>} */
237
+ const counts = {}
238
+
239
+ for (const row of rows) {
240
+ const typedRow = /**
241
+ * Narrows the runtime value to the documented type.
242
+ @type {Record<string, ?>} */ (row)
243
+
244
+ counts[String(typedRow.status)] = this._normalizeNumber(typedRow.count) || 0
245
+ }
246
+
247
+ return counts
248
+ })
249
+ }
250
+
251
+ /**
252
+ * Counts jobs matching the given filters.
253
+ * @param {object} [args] - Options.
254
+ * @param {string} [args.status] - Filter by status.
255
+ * @param {string} [args.jobName] - Filter by job name.
256
+ * @returns {Promise<number>} - Matching job count.
257
+ */
258
+ async countJobs({status, jobName} = {}) {
259
+ await this.ensureReady()
260
+
261
+ return await this._withDb(async (db) => {
262
+ let query = db.newQuery().from(JOBS_TABLE).select("COUNT(*) AS count")
263
+
264
+ if (status) query = query.where({status})
265
+ if (jobName) query = query.where({job_name: jobName})
266
+
267
+ const rows = await query.results()
268
+ const countRow = /**
269
+ * Narrows the runtime value to the documented type.
270
+ @type {Record<string, ?>} */ (rows[0] || {})
271
+
272
+ return this._normalizeNumber(countRow.count) || 0
273
+ })
274
+ }
275
+
276
+ /**
277
+ * Lists jobs for the dashboard, filtered, sorted and paginated.
278
+ * @param {object} [args] - Options.
279
+ * @param {string} [args.status] - Filter by status.
280
+ * @param {string} [args.jobName] - Filter by job name.
281
+ * @param {number} [args.limit] - Maximum rows to return.
282
+ * @param {number} [args.offset] - Rows to skip.
283
+ * @param {string} [args.sortColumn] - Camel-cased column to sort by (see SORTABLE_COLUMNS).
284
+ * @param {"ASC" | "DESC"} [args.sortDirection] - Sort direction.
285
+ * @returns {Promise<import("./types.js").BackgroundJobRow[]>} - Normalized job rows.
286
+ */
287
+ async listJobs({status, jobName, limit = 25, offset = 0, sortColumn = "createdAtMs", sortDirection = "DESC"} = {}) {
288
+ await this.ensureReady()
289
+
290
+ const column = SORTABLE_COLUMNS[sortColumn] || SORTABLE_COLUMNS.createdAtMs
291
+ const direction = sortDirection === "ASC" ? "ASC" : "DESC"
292
+
293
+ return await this._withDb(async (db) => {
294
+ let query = db.newQuery().from(JOBS_TABLE)
295
+
296
+ if (status) query = query.where({status})
297
+ if (jobName) query = query.where({job_name: jobName})
298
+
299
+ query = query.order({column, direction})
300
+ if (column !== SORTABLE_COLUMNS.createdAtMs) query = query.order({column: SORTABLE_COLUMNS.createdAtMs, direction: "DESC"})
301
+
302
+ const rows = await query.limit(limit).offset(offset).results()
303
+
304
+ return rows.map((row) => this._normalizeJobRow(row))
305
+ })
306
+ }
307
+
308
+ /**
309
+ * Runs mark handed off.
310
+ * @param {object} args - Options.
311
+ * @param {string} args.jobId - Job id.
312
+ * @param {string} [args.workerId] - Worker id.
313
+ * @returns {Promise<number>} - Resolves with handed off timestamp.
314
+ */
315
+ async markHandedOff({jobId, workerId}) {
316
+ await this.ensureReady()
317
+
318
+ const handedOffAtMs = Date.now()
319
+
320
+ await this._withDb(async (db) => {
321
+ await db.update({
322
+ tableName: JOBS_TABLE,
323
+ data: {
324
+ status: "handed_off",
325
+ handed_off_at_ms: handedOffAtMs,
326
+ worker_id: workerId || null
327
+ },
328
+ conditions: {id: jobId}
329
+ })
330
+ })
331
+
332
+ return handedOffAtMs
333
+ }
334
+
335
+ /**
336
+ * Runs mark completed.
337
+ * @param {object} args - Options.
338
+ * @param {string} args.jobId - Job id.
339
+ * @param {string} [args.workerId] - Worker id.
340
+ * @param {number} [args.handedOffAtMs] - Handed off timestamp.
341
+ * @returns {Promise<void>} - Resolves when updated.
342
+ */
343
+ async markCompleted({jobId, workerId, handedOffAtMs}) {
344
+ await this.ensureReady()
345
+
346
+ await this._withDb(async (db) => {
347
+ const job = await this._getJobRowById(db, jobId)
348
+
349
+ if (!job) return
350
+ if (!this._shouldAcceptReport({job, workerId, handedOffAtMs})) return
351
+
352
+ await db.update({
353
+ tableName: JOBS_TABLE,
354
+ data: {
355
+ status: "completed",
356
+ completed_at_ms: Date.now()
357
+ },
358
+ conditions: {id: jobId}
359
+ })
360
+ })
361
+ }
362
+
363
+ /**
364
+ * Runs mark returned to queue.
365
+ * @param {object} args - Options.
366
+ * @param {string} args.jobId - Job id.
367
+ * @returns {Promise<void>} - Resolves when updated.
368
+ */
369
+ async markReturnedToQueue({jobId}) {
370
+ await this.ensureReady()
371
+
372
+ await this._withDb(async (db) => {
373
+ await db.update({
374
+ tableName: JOBS_TABLE,
375
+ data: {
376
+ status: "queued",
377
+ scheduled_at_ms: Date.now(),
378
+ handed_off_at_ms: null,
379
+ worker_id: null
380
+ },
381
+ conditions: {id: jobId}
382
+ })
383
+ })
384
+ }
385
+
386
+ /**
387
+ * Runs mark failed.
388
+ * @param {object} args - Options.
389
+ * @param {string} args.jobId - Job id.
390
+ * @param {?} args.error - Error.
391
+ * @param {string} [args.workerId] - Worker id.
392
+ * @param {number} [args.handedOffAtMs] - Handed off timestamp.
393
+ * @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Updated job row when the report was accepted.
394
+ */
395
+ async markFailed({jobId, error, workerId, handedOffAtMs}) {
396
+ await this.ensureReady()
397
+
398
+ return await this._withDb(async (db) => {
399
+ const job = await this._getJobRowById(db, jobId)
400
+
401
+ if (!job) return null
402
+ if (!this._shouldAcceptReport({job, workerId, handedOffAtMs})) return null
403
+
404
+ return await this._applyFailure({db, job, error, markOrphaned: false})
405
+ })
406
+ }
407
+
408
+ /**
409
+ * Runs mark orphaned jobs.
410
+ * @param {object} [args] - Options.
411
+ * @param {number} [args.orphanedAfterMs] - Mark jobs orphaned after this duration.
412
+ * @returns {Promise<number>} - Count of orphaned jobs.
413
+ */
414
+ async markOrphanedJobs({orphanedAfterMs = ORPHANED_AFTER_MS} = {}) {
415
+ await this.ensureReady()
416
+
417
+ return await this._withDb(async (db) => {
418
+ const cutoff = Date.now() - orphanedAfterMs
419
+ const query = db
420
+ .newQuery()
421
+ .from(JOBS_TABLE)
422
+ .where({status: "handed_off"})
423
+ .where(`handed_off_at_ms <= ${db.quote(cutoff)}`)
424
+
425
+ const rows = await query.results()
426
+
427
+ for (const row of rows) {
428
+ const job = this._normalizeJobRow(row)
429
+
430
+ await this._applyFailure({
431
+ db,
432
+ job,
433
+ error: "Job orphaned after timeout",
434
+ markOrphaned: true
435
+ })
436
+ }
437
+
438
+ return rows.length
439
+ })
440
+ }
441
+
442
+ /**
443
+ * Runs clear all.
444
+ * @returns {Promise<void>} - Resolves when cleared.
445
+ */
446
+ async clearAll() {
447
+ await this.ensureReady()
448
+
449
+ await this._withDb(async (db) => {
450
+ await db.query(`DELETE FROM ${db.quoteTable(JOBS_TABLE)}`)
451
+ })
452
+ }
453
+
454
+ /**
455
+ * Runs get retry delay ms.
456
+ * @param {number} retryCount - Retry attempt count (1-based).
457
+ * @returns {number} - Delay in milliseconds.
458
+ */
459
+ getRetryDelayMs(retryCount) {
460
+ const scheduleSeconds = [10, 60, 600, 3600]
461
+
462
+ if (retryCount <= scheduleSeconds.length) {
463
+ return scheduleSeconds[retryCount - 1] * 1000
464
+ }
465
+
466
+ return (retryCount - 3) * 60 * 60 * 1000
467
+ }
468
+
469
+ /**
470
+ * Runs normalize max retries.
471
+ * @param {number | null | undefined} maxRetries - Input.
472
+ * @returns {number} - Normalized max retries.
473
+ */
474
+ _normalizeMaxRetries(maxRetries) {
475
+ if (typeof maxRetries === "number" && Number.isFinite(maxRetries) && maxRetries >= 0) {
476
+ return Math.floor(maxRetries)
477
+ }
478
+
479
+ return DEFAULT_MAX_RETRIES
480
+ }
481
+
482
+ async _ensureSchema() {
483
+ await this._withDb(async (db) => {
484
+ await this._ensureMigrationsTable(db)
485
+
486
+ const alreadyApplied = await this._hasMigration(db)
487
+
488
+ // Even when the migration row is present, the jobs table itself can have
489
+ // been dropped underneath us by a transaction rollback in another caller
490
+ // (DDL is transactional on SQLite/MSSQL). Verify the table physically
491
+ // exists and recreate it when missing rather than trusting the migration
492
+ // row alone, otherwise later callers fail with "no such table".
493
+ if (alreadyApplied && await db.tableExists(JOBS_TABLE)) {
494
+ await this._ensureJobsTableColumns(db)
495
+ return
496
+ }
497
+
498
+ await this._applyMigrations(db)
499
+ await this._ensureJobsTableColumns(db)
500
+
501
+ if (alreadyApplied) return
502
+
503
+ await this._recordMigration(db, MIGRATION_VERSION)
504
+ })
505
+ }
506
+
507
+ /**
508
+ * Runs ensure migrations table.
509
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
510
+ * @returns {Promise<void>} - Resolves when complete.
511
+ */
512
+ async _ensureMigrationsTable(db) {
513
+ if (await db.tableExists(MIGRATIONS_TABLE)) return
514
+
515
+ const table = new TableData(MIGRATIONS_TABLE, {ifNotExists: true})
516
+
517
+ table.string("key", {null: false, primaryKey: true})
518
+ table.string("scope", {null: false})
519
+ table.string("version", {null: false})
520
+ table.bigint("applied_at_ms", {null: false})
521
+
522
+ await db.createTable(table)
523
+ }
524
+
525
+ /**
526
+ * Runs has migration.
527
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
528
+ * @param {string} [version] - Migration version.
529
+ * @returns {Promise<boolean>} - Whether migration exists.
530
+ */
531
+ async _hasMigration(db, version = MIGRATION_VERSION) {
532
+ const query = db
533
+ .newQuery()
534
+ .from(MIGRATIONS_TABLE)
535
+ .where({key: this._migrationKey(version)})
536
+ .limit(1)
537
+
538
+ const rows = await query.results()
539
+
540
+ return rows.length > 0
541
+ }
542
+
543
+ /**
544
+ * Runs apply migrations.
545
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
546
+ * @returns {Promise<void>} - Resolves when complete.
547
+ */
548
+ async _applyMigrations(db) {
549
+ this.logger.info("Applying background jobs schema")
550
+
551
+ if (await db.tableExists(JOBS_TABLE)) {
552
+ this.logger.info("Background jobs table already exists - skipping create")
553
+ return
554
+ }
555
+
556
+ const table = new TableData(JOBS_TABLE, {ifNotExists: true})
557
+
558
+ table.string("id", {primaryKey: true})
559
+ table.string("job_name", {null: false, index: true})
560
+ table.text("args_json", {null: false})
561
+ table.boolean("forked", {null: false})
562
+ table.string("execution_mode", {null: false})
563
+ table.integer("max_retries", {null: false})
564
+ table.integer("attempts", {null: false})
565
+ table.string("status", {null: false, index: true})
566
+ table.bigint("scheduled_at_ms", {null: false, index: true})
567
+ table.bigint("created_at_ms", {null: false, index: true})
568
+ table.bigint("handed_off_at_ms", {null: true, index: true})
569
+ table.bigint("completed_at_ms", {null: true})
570
+ table.bigint("failed_at_ms", {null: true})
571
+ table.bigint("orphaned_at_ms", {null: true, index: true})
572
+ table.string("worker_id", {null: true})
573
+ table.text("last_error", {null: true})
574
+
575
+ await db.createTable(table)
576
+ }
577
+
578
+ /**
579
+ * Runs ensure jobs table columns.
580
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
581
+ * @returns {Promise<void>} - Resolves when complete.
582
+ */
583
+ async _ensureJobsTableColumns(db) {
584
+ if (!(await db.tableExists(JOBS_TABLE))) return
585
+
586
+ const table = await db.getTableByNameOrFail(JOBS_TABLE)
587
+ const executionModeColumn = await table.getColumnByName("execution_mode")
588
+
589
+ if (!executionModeColumn) {
590
+ const tableData = new TableData(JOBS_TABLE)
591
+ tableData.string("execution_mode", {null: true})
592
+ const sqls = await db.alterTableSQLs(tableData)
593
+
594
+ for (const sql of sqls) {
595
+ await db.query(sql)
596
+ }
597
+
598
+ db.clearSchemaCache()
599
+ }
600
+
601
+ await this._backfillExecutionModesOnce(db)
602
+ }
603
+
604
+ /**
605
+ * Runs backfill execution modes once.
606
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
607
+ * @returns {Promise<void>} - Resolves when complete.
608
+ */
609
+ async _backfillExecutionModesOnce(db) {
610
+ const migrationVersion = EXECUTION_MODE_BACKFILL_MIGRATION_VERSION
611
+ const migrationKey = this._migrationKey(migrationVersion)
612
+
613
+ if (await this._hasMigration(db, migrationVersion)) return
614
+
615
+ await db.acquireAdvisoryLock(migrationKey)
616
+
617
+ try {
618
+ if (await this._hasMigration(db, migrationVersion)) return
619
+
620
+ const tableNameSql = db.quoteTable(JOBS_TABLE)
621
+ const forkedColumnSql = db.quoteColumn("forked")
622
+ const executionModeColumnSql = db.quoteColumn("execution_mode")
623
+
624
+ await db.query(
625
+ `UPDATE ${tableNameSql} SET ${executionModeColumnSql} = ${db.quote(DEFAULT_EXECUTION_MODE)} ` +
626
+ `WHERE ${forkedColumnSql} = ${db.quote(true)} AND ${executionModeColumnSql} IS NULL`
627
+ )
628
+ await db.query(
629
+ `UPDATE ${tableNameSql} SET ${executionModeColumnSql} = ${db.quote("inline")} ` +
630
+ `WHERE ${forkedColumnSql} = ${db.quote(false)} AND ${executionModeColumnSql} IS NULL`
631
+ )
632
+
633
+ await this._recordMigration(db, migrationVersion)
634
+ } finally {
635
+ await db.releaseAdvisoryLock(migrationKey)
636
+ }
637
+ }
638
+
639
+ /**
640
+ * Runs record migration.
641
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
642
+ * @param {string} version - Migration version.
643
+ * @returns {Promise<void>} - Resolves when complete.
644
+ */
645
+ async _recordMigration(db, version) {
646
+ await db.insert({
647
+ tableName: MIGRATIONS_TABLE,
648
+ data: {
649
+ key: this._migrationKey(version),
650
+ scope: MIGRATION_SCOPE,
651
+ version,
652
+ applied_at_ms: Date.now()
653
+ }
654
+ })
655
+ }
656
+
657
+ async _initializeModel() {
658
+ BackgroundJobRecord.setDatabaseIdentifier(this.getDatabaseIdentifier())
659
+
660
+ if (BackgroundJobRecord.isInitialized()) return
661
+
662
+ const pool = this.configuration.getDatabasePool(this.getDatabaseIdentifier())
663
+
664
+ await pool.withConnection({name: "Background jobs store initialize model"}, async () => {
665
+ await BackgroundJobRecord.initializeRecord({configuration: this.configuration})
666
+ })
667
+ }
668
+
669
+ /**
670
+ * Runs get job row by id.
671
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
672
+ * @param {string} jobId - Job id.
673
+ * @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Job row.
674
+ */
675
+ async _getJobRowById(db, jobId) {
676
+ const query = db
677
+ .newQuery()
678
+ .from(JOBS_TABLE)
679
+ .where({id: jobId})
680
+ .limit(1)
681
+
682
+ const rows = await query.results()
683
+
684
+ if (!rows[0]) return null
685
+
686
+ return this._normalizeJobRow(rows[0])
687
+ }
688
+
689
+ /**
690
+ * Runs apply failure.
691
+ * @param {object} args - Options.
692
+ * @param {import("../database/drivers/base.js").default} args.db - Database connection.
693
+ * @param {import("./types.js").BackgroundJobRow} args.job - Job row.
694
+ * @param {?} args.error - Error.
695
+ * @param {boolean} args.markOrphaned - Whether marking orphaned.
696
+ * @returns {Promise<import("./types.js").BackgroundJobRow>} - Updated job row.
697
+ */
698
+ async _applyFailure({db, job, error, markOrphaned}) {
699
+ const now = Date.now()
700
+ const nextAttempt = (job.attempts || 0) + 1
701
+ const maxRetries = this._normalizeMaxRetries(job.maxRetries)
702
+ const shouldRetry = nextAttempt <= maxRetries
703
+ const failureMessage = normalizeBackgroundJobError(error)
704
+ const scheduledAt = shouldRetry ? now + this.getRetryDelayMs(nextAttempt) : job.scheduledAtMs
705
+ const update = this._failureUpdate({
706
+ failureMessage,
707
+ markOrphaned,
708
+ nextAttempt,
709
+ now,
710
+ scheduledAt,
711
+ shouldRetry
712
+ })
713
+
714
+ await db.update({
715
+ tableName: JOBS_TABLE,
716
+ data: update,
717
+ conditions: {id: job.id}
718
+ })
719
+
720
+ return this._jobWithFailureUpdate({failureMessage, job, nextAttempt, update})
721
+ }
722
+
723
+ /**
724
+ * Runs failure update.
725
+ * @param {object} args - Options.
726
+ * @param {string} args.failureMessage - Last failure message.
727
+ * @param {boolean} args.markOrphaned - Whether marking orphaned.
728
+ * @param {number} args.nextAttempt - Next attempt count.
729
+ * @param {number} args.now - Current timestamp.
730
+ * @param {number | null} args.scheduledAt - Next scheduled timestamp.
731
+ * @param {boolean} args.shouldRetry - Whether the job should retry.
732
+ * @returns {Record<string, ?>} - Database update data.
733
+ */
734
+ _failureUpdate({failureMessage, markOrphaned, nextAttempt, now, scheduledAt, shouldRetry}) {
735
+ /**
736
+ * Update.
737
+ @type {Record<string, ?>} */
738
+ const update = {
739
+ attempts: nextAttempt,
740
+ handed_off_at_ms: null,
741
+ worker_id: null,
742
+ last_error: failureMessage
743
+ }
744
+
745
+ this._applyOrphanedFailureUpdate({markOrphaned, now, update})
746
+ this._applyFailureStatusUpdate({markOrphaned, now, scheduledAt, shouldRetry, update})
747
+
748
+ return update
749
+ }
750
+
751
+ /**
752
+ * Runs apply orphaned failure update.
753
+ * @param {object} args - Options.
754
+ * @param {boolean} args.markOrphaned - Whether marking orphaned.
755
+ * @param {number} args.now - Current timestamp.
756
+ * @param {Record<string, ?>} args.update - Database update data.
757
+ * @returns {void}
758
+ */
759
+ _applyOrphanedFailureUpdate({markOrphaned, now, update}) {
760
+ if (markOrphaned) update.orphaned_at_ms = now
761
+ }
762
+
763
+ /**
764
+ * Runs apply failure status update.
765
+ * @param {object} args - Options.
766
+ * @param {boolean} args.markOrphaned - Whether marking orphaned.
767
+ * @param {number} args.now - Current timestamp.
768
+ * @param {number | null} args.scheduledAt - Next scheduled timestamp.
769
+ * @param {boolean} args.shouldRetry - Whether the job should retry.
770
+ * @param {Record<string, ?>} args.update - Database update data.
771
+ * @returns {void}
772
+ */
773
+ _applyFailureStatusUpdate({markOrphaned, now, scheduledAt, shouldRetry, update}) {
774
+ if (shouldRetry) {
775
+ update.status = "queued"
776
+ update.scheduled_at_ms = scheduledAt
777
+ return
778
+ }
779
+
780
+ if (markOrphaned) {
781
+ update.status = "orphaned"
782
+ return
783
+ }
784
+
785
+ update.status = "failed"
786
+ update.failed_at_ms = now
787
+ }
788
+
789
+ /**
790
+ * Runs job with failure update.
791
+ * @param {object} args - Options.
792
+ * @param {string} args.failureMessage - Last failure message.
793
+ * @param {import("./types.js").BackgroundJobRow} args.job - Job row.
794
+ * @param {number} args.nextAttempt - Next attempt count.
795
+ * @param {Record<string, ?>} args.update - Database update data.
796
+ * @returns {import("./types.js").BackgroundJobRow} - Updated job row.
797
+ */
798
+ _jobWithFailureUpdate({failureMessage, job, nextAttempt, update}) {
799
+ return {
800
+ ...job,
801
+ attempts: nextAttempt,
802
+ failedAtMs: update.failed_at_ms ?? job.failedAtMs,
803
+ handedOffAtMs: null,
804
+ lastError: failureMessage,
805
+ orphanedAtMs: update.orphaned_at_ms ?? job.orphanedAtMs,
806
+ scheduledAtMs: update.scheduled_at_ms ?? job.scheduledAtMs,
807
+ status: update.status,
808
+ workerId: null
809
+ }
810
+ }
811
+
812
+ /**
813
+ * Runs normalize job row.
814
+ * @param {Record<string, ?>} row - Raw database row.
815
+ * @returns {import("./types.js").BackgroundJobRow} - Normalized job row.
816
+ */
817
+ _normalizeJobRow(row) {
818
+ const executionMode = row.execution_mode
819
+ ? this._normalizeExecutionModeName(String(row.execution_mode))
820
+ : this._normalizeExecutionMode({forked: this._normalizeBoolean(row.forked)})
821
+
822
+ return {
823
+ id: String(row.id),
824
+ jobName: String(row.job_name),
825
+ args: this._parseArgs(row.args_json),
826
+ executionMode,
827
+ forked: executionMode !== "inline",
828
+ status: row.status ? String(row.status) : "queued",
829
+ attempts: this._normalizeNumber(row.attempts),
830
+ maxRetries: this._normalizeNumber(row.max_retries),
831
+ scheduledAtMs: this._normalizeNumber(row.scheduled_at_ms),
832
+ createdAtMs: this._normalizeNumber(row.created_at_ms),
833
+ handedOffAtMs: this._normalizeNumber(row.handed_off_at_ms),
834
+ completedAtMs: this._normalizeNumber(row.completed_at_ms),
835
+ failedAtMs: this._normalizeNumber(row.failed_at_ms),
836
+ orphanedAtMs: this._normalizeNumber(row.orphaned_at_ms),
837
+ workerId: row.worker_id ? String(row.worker_id) : null,
838
+ lastError: row.last_error ? String(row.last_error) : null
839
+ }
840
+ }
841
+
842
+ /**
843
+ * Runs normalize number.
844
+ * @param {?} value - Input value.
845
+ * @returns {number | null} - Normalized number.
846
+ */
847
+ _normalizeNumber(value) {
848
+ if (value === null || value === undefined || value === "") return null
849
+
850
+ const numeric = Number(value)
851
+
852
+ if (Number.isNaN(numeric)) return null
853
+
854
+ return numeric
855
+ }
856
+
857
+ /**
858
+ * Runs normalize boolean.
859
+ * @param {?} value - Input value.
860
+ * @returns {boolean} - Normalized boolean.
861
+ */
862
+ _normalizeBoolean(value) {
863
+ if (value === null || value === undefined) return false
864
+ if (typeof value === "boolean") return value
865
+ if (typeof value === "number") return value !== 0
866
+
867
+ return value === "true"
868
+ }
869
+
870
+ /**
871
+ * Runs normalize execution mode.
872
+ * @param {import("./types.js").BackgroundJobOptions} [options] - Job options.
873
+ * @returns {import("./types.js").BackgroundJobExecutionMode} - Normalized execution mode.
874
+ */
875
+ _normalizeExecutionMode(options) {
876
+ const executionMode = options?.executionMode
877
+
878
+ if (executionMode) {
879
+ return this._normalizeExecutionModeName(executionMode)
880
+ }
881
+ if (options?.forked === false) return "inline"
882
+
883
+ return DEFAULT_EXECUTION_MODE
884
+ }
885
+
886
+ /**
887
+ * Runs normalize execution mode name.
888
+ * @param {string} executionMode - Execution mode name.
889
+ * @returns {import("./types.js").BackgroundJobExecutionMode} - Normalized execution mode.
890
+ */
891
+ _normalizeExecutionModeName(executionMode) {
892
+ for (const mode of EXECUTION_MODES) {
893
+ if (mode === executionMode) return mode
894
+ }
895
+
896
+ throw new Error(`Invalid background job executionMode: ${executionMode}`)
897
+ }
898
+
899
+ /**
900
+ * Runs parse args.
901
+ * @param {?} value - Input value.
902
+ * @returns {Array<?>} - Parsed args.
903
+ */
904
+ _parseArgs(value) {
905
+ if (!value) return []
906
+
907
+ try {
908
+ const parsed = JSON.parse(String(value))
909
+
910
+ if (Array.isArray(parsed)) return parsed
911
+ } catch {
912
+ // Ignore parse errors.
913
+ }
914
+
915
+ return []
916
+ }
917
+
918
+ /**
919
+ * Runs with db.
920
+ * @template T
921
+ * @param {(db: import("../database/drivers/base.js").default) => Promise<T>} callback - Callback.
922
+ * @returns {Promise<T>} - Callback result.
923
+ */
924
+ async _withDb(callback) {
925
+ const pool = this.configuration.getDatabasePool(this.getDatabaseIdentifier())
926
+ let callbackCalled = false
927
+ /**
928
+ * Defines result.
929
+ @type {T | undefined} */
930
+ let result
931
+
932
+ await pool.withConnection({name: "Background jobs store"}, async (db) => {
933
+ callbackCalled = true
934
+ result = await callback(db)
935
+ })
936
+
937
+ if (!callbackCalled) {
938
+ throw new Error("Background jobs store callback was not invoked")
939
+ }
940
+
941
+ return /** Narrows the runtime value to the documented type. @type {T} */ (result)
942
+ }
943
+
944
+ /**
945
+ * Runs should accept report.
946
+ * @param {object} args - Options.
947
+ * @param {import("./types.js").BackgroundJobRow} args.job - Job row.
948
+ * @param {string | null | undefined} args.workerId - Worker id from report.
949
+ * @param {number | null | undefined} args.handedOffAtMs - Handed off timestamp from report.
950
+ * @returns {boolean} - Whether to accept the report.
951
+ */
952
+ _shouldAcceptReport({job, workerId, handedOffAtMs}) {
953
+ if (job.status !== "handed_off") return false
954
+
955
+ return this._workerReportMatches({job, workerId}) && this._handoffReportMatches({handedOffAtMs, job})
956
+ }
957
+
958
+ /**
959
+ * Runs worker report matches.
960
+ * @param {object} args - Options.
961
+ * @param {import("./types.js").BackgroundJobRow} args.job - Job row.
962
+ * @param {string | null | undefined} args.workerId - Worker id from report.
963
+ * @returns {boolean} - Whether the worker report matches.
964
+ */
965
+ _workerReportMatches({job, workerId}) {
966
+ if (!workerId) return true
967
+ if (!job.workerId) return true
968
+
969
+ return workerId === job.workerId
970
+ }
971
+
972
+ /**
973
+ * Runs handoff report matches.
974
+ * @param {object} args - Options.
975
+ * @param {number | null | undefined} args.handedOffAtMs - Handed off timestamp from report.
976
+ * @param {import("./types.js").BackgroundJobRow} args.job - Job row.
977
+ * @returns {boolean} - Whether the handoff report matches.
978
+ */
979
+ _handoffReportMatches({handedOffAtMs, job}) {
980
+ if (!handedOffAtMs) return true
981
+ if (!job.handedOffAtMs) return true
982
+
983
+ return handedOffAtMs === job.handedOffAtMs
984
+ }
985
+
986
+ /**
987
+ * Runs migration key.
988
+ * @param {string} [version] - Migration version.
989
+ * @returns {string} - Migration key.
990
+ */
991
+ _migrationKey(version = MIGRATION_VERSION) {
992
+ return `${MIGRATION_SCOPE}:${version}`
993
+ }
994
+ }