velocious 1.0.514 → 1.0.516

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 (255) hide show
  1. package/README.md +4 -3
  2. package/build/background-jobs/cron-expression.js +9 -9
  3. package/build/background-jobs/forked-runner-child.js +1 -1
  4. package/build/background-jobs/job-runner.js +21 -15
  5. package/build/background-jobs/json-socket.js +4 -0
  6. package/build/background-jobs/main.js +180 -18
  7. package/build/background-jobs/status-reporter.js +12 -5
  8. package/build/background-jobs/store.js +132 -50
  9. package/build/background-jobs/types.js +11 -3
  10. package/build/background-jobs/worker.js +9 -5
  11. package/build/beacon/client.js +13 -6
  12. package/build/configuration.js +54 -29
  13. package/build/controller.js +9 -3
  14. package/build/database/drivers/sqlite/base.js +1 -1
  15. package/build/database/drivers/sqlite/index.js +15 -14
  16. package/build/database/migrations-ledger.js +16 -16
  17. package/build/database/pool/async-tracked-multi-connection.js +16 -0
  18. package/build/database/pool/base.js +26 -0
  19. package/build/database/query/where-model-class-hash.js +2 -0
  20. package/build/database/query/with-count.js +1 -1
  21. package/build/database/record/acts-as-list.js +2 -2
  22. package/build/database/record/auditing.js +23 -6
  23. package/build/database/record/index.js +7 -7
  24. package/build/database/record/validators/uniqueness.js +3 -3
  25. package/build/database/tenants/data-copier.js +23 -23
  26. package/build/database/tenants/schema-cloner.js +27 -27
  27. package/build/environment-handlers/browser.js +0 -1
  28. package/build/environment-handlers/node/cli/commands/background-jobs-runner.js +2 -1
  29. package/build/environment-handlers/node/cli/commands/lint/relationships.js +2 -2
  30. package/build/environment-handlers/node.js +1 -1
  31. package/build/frontend-model-controller.js +26 -18
  32. package/build/frontend-model-resource/base-resource.js +4 -4
  33. package/build/frontend-models/base.js +5 -5
  34. package/build/frontend-models/query.js +12 -12
  35. package/build/http-server/client/index.js +61 -15
  36. package/build/http-server/client/request-runner.js +7 -1
  37. package/build/http-server/client/response.js +17 -1
  38. package/build/http-server/client/websocket-session.js +13 -13
  39. package/build/http-server/server-client.js +96 -0
  40. package/build/http-server/websocket-channel.js +12 -11
  41. package/build/http-server/websocket-connection.js +12 -11
  42. package/build/http-server/websocket-events-host.js +1 -1
  43. package/build/http-server/worker-handler/in-process.js +48 -9
  44. package/build/http-server/worker-handler/index.js +67 -7
  45. package/build/http-server/worker-handler/worker-thread.js +68 -0
  46. package/build/src/background-jobs/cron-expression.d.ts +2 -2
  47. package/build/src/background-jobs/cron-expression.js +10 -10
  48. package/build/src/background-jobs/forked-runner-child.js +2 -2
  49. package/build/src/background-jobs/job-runner.d.ts +5 -1
  50. package/build/src/background-jobs/job-runner.d.ts.map +1 -1
  51. package/build/src/background-jobs/job-runner.js +22 -16
  52. package/build/src/background-jobs/json-socket.d.ts +4 -0
  53. package/build/src/background-jobs/json-socket.d.ts.map +1 -1
  54. package/build/src/background-jobs/json-socket.js +5 -1
  55. package/build/src/background-jobs/main.d.ts +62 -10
  56. package/build/src/background-jobs/main.d.ts.map +1 -1
  57. package/build/src/background-jobs/main.js +171 -19
  58. package/build/src/background-jobs/status-reporter.d.ts +6 -2
  59. package/build/src/background-jobs/status-reporter.d.ts.map +1 -1
  60. package/build/src/background-jobs/status-reporter.js +13 -6
  61. package/build/src/background-jobs/store.d.ts +48 -25
  62. package/build/src/background-jobs/store.d.ts.map +1 -1
  63. package/build/src/background-jobs/store.js +123 -50
  64. package/build/src/background-jobs/types.d.ts +36 -3
  65. package/build/src/background-jobs/types.d.ts.map +1 -1
  66. package/build/src/background-jobs/types.js +12 -4
  67. package/build/src/background-jobs/worker.d.ts +7 -5
  68. package/build/src/background-jobs/worker.d.ts.map +1 -1
  69. package/build/src/background-jobs/worker.js +10 -6
  70. package/build/src/beacon/client.d.ts +6 -3
  71. package/build/src/beacon/client.d.ts.map +1 -1
  72. package/build/src/beacon/client.js +14 -7
  73. package/build/src/configuration-types.d.ts +1 -1
  74. package/build/src/configuration.d.ts +42 -29
  75. package/build/src/configuration.d.ts.map +1 -1
  76. package/build/src/configuration.js +52 -30
  77. package/build/src/controller.d.ts +3 -0
  78. package/build/src/controller.d.ts.map +1 -1
  79. package/build/src/controller.js +9 -4
  80. package/build/src/database/drivers/sqlite/base.js +2 -2
  81. package/build/src/database/drivers/sqlite/index.d.ts +7 -6
  82. package/build/src/database/drivers/sqlite/index.d.ts.map +1 -1
  83. package/build/src/database/drivers/sqlite/index.js +16 -15
  84. package/build/src/database/migrations-ledger.d.ts +16 -16
  85. package/build/src/database/migrations-ledger.js +17 -17
  86. package/build/src/database/pool/async-tracked-multi-connection.d.ts +0 -11
  87. package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
  88. package/build/src/database/pool/async-tracked-multi-connection.js +16 -1
  89. package/build/src/database/pool/base.d.ts +21 -0
  90. package/build/src/database/pool/base.d.ts.map +1 -1
  91. package/build/src/database/pool/base.js +24 -1
  92. package/build/src/database/query/where-model-class-hash.d.ts.map +1 -1
  93. package/build/src/database/query/where-model-class-hash.js +3 -1
  94. package/build/src/database/query/with-count.js +2 -2
  95. package/build/src/database/record/acts-as-list.js +3 -3
  96. package/build/src/database/record/auditing.d.ts +1 -1
  97. package/build/src/database/record/auditing.d.ts.map +1 -1
  98. package/build/src/database/record/auditing.js +24 -7
  99. package/build/src/database/record/index.d.ts +7 -7
  100. package/build/src/database/record/index.js +8 -8
  101. package/build/src/database/record/validators/uniqueness.d.ts +3 -3
  102. package/build/src/database/record/validators/uniqueness.js +4 -4
  103. package/build/src/database/tenants/data-copier.d.ts +18 -18
  104. package/build/src/database/tenants/data-copier.js +24 -24
  105. package/build/src/database/tenants/schema-cloner.d.ts +27 -27
  106. package/build/src/database/tenants/schema-cloner.js +28 -28
  107. package/build/src/environment-handlers/browser.d.ts +9 -0
  108. package/build/src/environment-handlers/browser.d.ts.map +1 -1
  109. package/build/src/environment-handlers/browser.js +1 -2
  110. package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.d.ts.map +1 -1
  111. package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.js +3 -2
  112. package/build/src/environment-handlers/node/cli/commands/lint/relationships.js +3 -3
  113. package/build/src/environment-handlers/node.js +2 -2
  114. package/build/src/frontend-model-controller.d.ts +9 -8
  115. package/build/src/frontend-model-controller.d.ts.map +1 -1
  116. package/build/src/frontend-model-controller.js +26 -19
  117. package/build/src/frontend-model-resource/base-resource.js +5 -5
  118. package/build/src/frontend-models/base.d.ts +4 -4
  119. package/build/src/frontend-models/base.d.ts.map +1 -1
  120. package/build/src/frontend-models/base.js +6 -6
  121. package/build/src/frontend-models/query.d.ts +7 -7
  122. package/build/src/frontend-models/query.js +13 -13
  123. package/build/src/http-server/client/index.d.ts +23 -1
  124. package/build/src/http-server/client/index.d.ts.map +1 -1
  125. package/build/src/http-server/client/index.js +55 -17
  126. package/build/src/http-server/client/request-runner.d.ts.map +1 -1
  127. package/build/src/http-server/client/request-runner.js +8 -2
  128. package/build/src/http-server/client/response.d.ts +11 -1
  129. package/build/src/http-server/client/response.d.ts.map +1 -1
  130. package/build/src/http-server/client/response.js +16 -2
  131. package/build/src/http-server/client/websocket-session.d.ts +13 -13
  132. package/build/src/http-server/client/websocket-session.js +14 -14
  133. package/build/src/http-server/server-client.d.ts +13 -0
  134. package/build/src/http-server/server-client.d.ts.map +1 -1
  135. package/build/src/http-server/server-client.js +94 -1
  136. package/build/src/http-server/websocket-channel.d.ts +12 -11
  137. package/build/src/http-server/websocket-channel.d.ts.map +1 -1
  138. package/build/src/http-server/websocket-channel.js +13 -12
  139. package/build/src/http-server/websocket-connection.d.ts +12 -11
  140. package/build/src/http-server/websocket-connection.d.ts.map +1 -1
  141. package/build/src/http-server/websocket-connection.js +13 -12
  142. package/build/src/http-server/websocket-events-host.d.ts +1 -1
  143. package/build/src/http-server/websocket-events-host.js +2 -2
  144. package/build/src/http-server/worker-handler/in-process.d.ts +2 -0
  145. package/build/src/http-server/worker-handler/in-process.d.ts.map +1 -1
  146. package/build/src/http-server/worker-handler/in-process.js +42 -11
  147. package/build/src/http-server/worker-handler/index.d.ts +21 -0
  148. package/build/src/http-server/worker-handler/index.d.ts.map +1 -1
  149. package/build/src/http-server/worker-handler/index.js +61 -7
  150. package/build/src/http-server/worker-handler/worker-thread.d.ts +30 -0
  151. package/build/src/http-server/worker-handler/worker-thread.d.ts.map +1 -1
  152. package/build/src/http-server/worker-handler/worker-thread.js +61 -1
  153. package/build/src/sync/device-identity.d.ts +2 -2
  154. package/build/src/sync/device-identity.d.ts.map +1 -1
  155. package/build/src/sync/device-identity.js +4 -4
  156. package/build/src/sync/local-mutation-log.d.ts +0 -1
  157. package/build/src/sync/local-mutation-log.d.ts.map +1 -1
  158. package/build/src/sync/local-mutation-log.js +1 -2
  159. package/build/src/sync/query-scope.d.ts +5 -0
  160. package/build/src/sync/query-scope.d.ts.map +1 -1
  161. package/build/src/sync/query-scope.js +7 -2
  162. package/build/src/sync/sync-client-types.d.ts +2 -2
  163. package/build/src/sync/sync-client-types.d.ts.map +1 -1
  164. package/build/src/sync/sync-client-types.js +1 -1
  165. package/build/src/sync/sync-client.d.ts +17 -2
  166. package/build/src/sync/sync-client.d.ts.map +1 -1
  167. package/build/src/sync/sync-client.js +28 -14
  168. package/build/src/sync/sync-realtime-bridge.d.ts +6 -2
  169. package/build/src/sync/sync-realtime-bridge.d.ts.map +1 -1
  170. package/build/src/sync/sync-realtime-bridge.js +14 -3
  171. package/build/src/sync/sync-resource-base.d.ts +14 -3
  172. package/build/src/sync/sync-resource-base.d.ts.map +1 -1
  173. package/build/src/sync/sync-resource-base.js +20 -4
  174. package/build/src/sync/sync-scope-store.d.ts +3 -3
  175. package/build/src/sync/sync-scope-store.d.ts.map +1 -1
  176. package/build/src/sync/sync-scope-store.js +7 -5
  177. package/build/src/sync/sync-websocket-channel.d.ts +10 -0
  178. package/build/src/sync/sync-websocket-channel.d.ts.map +1 -1
  179. package/build/src/sync/sync-websocket-channel.js +20 -3
  180. package/build/src/tenants/tenant-iterator.d.ts +8 -8
  181. package/build/src/tenants/tenant-iterator.js +9 -9
  182. package/build/src/tenants/tenant.d.ts +6 -6
  183. package/build/src/tenants/tenant.js +7 -7
  184. package/build/src/testing/test-runner.d.ts +16 -0
  185. package/build/src/testing/test-runner.d.ts.map +1 -1
  186. package/build/src/testing/test-runner.js +79 -19
  187. package/build/sync/device-identity.js +3 -3
  188. package/build/sync/local-mutation-log.js +0 -1
  189. package/build/sync/query-scope.js +6 -1
  190. package/build/sync/sync-client-types.js +1 -1
  191. package/build/sync/sync-client.js +28 -15
  192. package/build/sync/sync-realtime-bridge.js +13 -2
  193. package/build/sync/sync-resource-base.js +20 -3
  194. package/build/sync/sync-scope-store.js +6 -4
  195. package/build/sync/sync-websocket-channel.js +18 -2
  196. package/build/tenants/tenant-iterator.js +8 -8
  197. package/build/tenants/tenant.js +6 -6
  198. package/build/testing/test-runner.js +86 -20
  199. package/package.json +2 -2
  200. package/src/background-jobs/cron-expression.js +9 -9
  201. package/src/background-jobs/forked-runner-child.js +1 -1
  202. package/src/background-jobs/job-runner.js +21 -15
  203. package/src/background-jobs/json-socket.js +4 -0
  204. package/src/background-jobs/main.js +180 -18
  205. package/src/background-jobs/status-reporter.js +12 -5
  206. package/src/background-jobs/store.js +132 -50
  207. package/src/background-jobs/types.js +11 -3
  208. package/src/background-jobs/worker.js +9 -5
  209. package/src/beacon/client.js +13 -6
  210. package/src/configuration.js +54 -29
  211. package/src/controller.js +9 -3
  212. package/src/database/drivers/sqlite/base.js +1 -1
  213. package/src/database/drivers/sqlite/index.js +15 -14
  214. package/src/database/migrations-ledger.js +16 -16
  215. package/src/database/pool/async-tracked-multi-connection.js +16 -0
  216. package/src/database/pool/base.js +26 -0
  217. package/src/database/query/where-model-class-hash.js +2 -0
  218. package/src/database/query/with-count.js +1 -1
  219. package/src/database/record/acts-as-list.js +2 -2
  220. package/src/database/record/auditing.js +23 -6
  221. package/src/database/record/index.js +7 -7
  222. package/src/database/record/validators/uniqueness.js +3 -3
  223. package/src/database/tenants/data-copier.js +23 -23
  224. package/src/database/tenants/schema-cloner.js +27 -27
  225. package/src/environment-handlers/browser.js +0 -1
  226. package/src/environment-handlers/node/cli/commands/background-jobs-runner.js +2 -1
  227. package/src/environment-handlers/node/cli/commands/lint/relationships.js +2 -2
  228. package/src/environment-handlers/node.js +1 -1
  229. package/src/frontend-model-controller.js +26 -18
  230. package/src/frontend-model-resource/base-resource.js +4 -4
  231. package/src/frontend-models/base.js +5 -5
  232. package/src/frontend-models/query.js +12 -12
  233. package/src/http-server/client/index.js +61 -15
  234. package/src/http-server/client/request-runner.js +7 -1
  235. package/src/http-server/client/response.js +17 -1
  236. package/src/http-server/client/websocket-session.js +13 -13
  237. package/src/http-server/server-client.js +96 -0
  238. package/src/http-server/websocket-channel.js +12 -11
  239. package/src/http-server/websocket-connection.js +12 -11
  240. package/src/http-server/websocket-events-host.js +1 -1
  241. package/src/http-server/worker-handler/in-process.js +48 -9
  242. package/src/http-server/worker-handler/index.js +67 -7
  243. package/src/http-server/worker-handler/worker-thread.js +68 -0
  244. package/src/sync/device-identity.js +3 -3
  245. package/src/sync/local-mutation-log.js +0 -1
  246. package/src/sync/query-scope.js +6 -1
  247. package/src/sync/sync-client-types.js +1 -1
  248. package/src/sync/sync-client.js +28 -15
  249. package/src/sync/sync-realtime-bridge.js +13 -2
  250. package/src/sync/sync-resource-base.js +20 -3
  251. package/src/sync/sync-scope-store.js +6 -4
  252. package/src/sync/sync-websocket-channel.js +18 -2
  253. package/src/tenants/tenant-iterator.js +8 -8
  254. package/src/tenants/tenant.js +6 -6
  255. package/src/testing/test-runner.js +86 -20
@@ -74,7 +74,12 @@ let globalEventConnections = {}
74
74
 
75
75
  /** @type {AuditEventsType} */
76
76
  const AuditEvents = {
77
- /** Fire all registered callbacks for a model type + action. @param {string} type @param {string} action @param {AuditEventPayload} args */
77
+ /**
78
+ * Fire all registered callbacks for a model type and action.
79
+ * @param {string} type - Audited model type whose listeners should fire.
80
+ * @param {string} action - Audit action whose listeners should fire.
81
+ * @param {AuditEventPayload} args - Audit event delivered to matching listeners.
82
+ */
78
83
  call(type, action, args) {
79
84
  const actions = globalEventConnections[type] || {}
80
85
  const callbacks = actions[action] || []
@@ -84,7 +89,13 @@ const AuditEvents = {
84
89
  }
85
90
  },
86
91
 
87
- /** Register a callback for a model type + action. Returns an unsubscribe function. @param {string} type @param {string} action @param {(args: AuditEventPayload) => void} callback @returns {() => void} */
92
+ /**
93
+ * Register a callback for a model type and action.
94
+ * @param {string} type - Audited model type to observe.
95
+ * @param {string} action - Audit action to observe.
96
+ * @param {(args: AuditEventPayload) => void} callback - Listener invoked for matching audit events.
97
+ * @returns {() => void} - Callback that removes the registration.
98
+ */
88
99
  connect(type, action, callback) {
89
100
  if (!globalEventConnections[type]) {
90
101
  globalEventConnections[type] = {}
@@ -109,7 +120,7 @@ const AuditEvents = {
109
120
  }
110
121
  },
111
122
 
112
- /** Clear all registered callbacks. @returns {void} */
123
+ /** Clear all registered callbacks. */
113
124
  reset() {
114
125
  globalEventConnections = {}
115
126
  }
@@ -244,7 +255,10 @@ function sharedAuditClass(modelClass) {
244
255
  * Framework-owned Audit model for the shared `audits` table.
245
256
  */
246
257
  class Audit extends dbRecordClass {
247
- /** Returns the backing table name. @returns {string} */
258
+ /**
259
+ * Returns the backing table name.
260
+ * @returns {string} - Shared `audits` table name.
261
+ */
248
262
  static tableName() {
249
263
  return "audits"
250
264
  }
@@ -291,7 +305,10 @@ function dedicatedAuditClass(modelClass, tableName) {
291
305
  * Framework-owned per-model Audit class.
292
306
  */
293
307
  class ModelAudit extends dbRecordClass {
294
- /** Returns the backing table name. @returns {string} */
308
+ /**
309
+ * Returns the backing table name.
310
+ * @returns {string} - Dedicated audit table supplied for this model class.
311
+ */
295
312
  static tableName() {
296
313
  return tableName
297
314
  }
@@ -906,7 +923,7 @@ function normalizeAction(action) {
906
923
  * Creates the shared audit tables migration up/down callbacks for use inside
907
924
  * a Migration class. The `table` parameter is a Migration instance.
908
925
  * @param {{id?: {type: string}}} [options] - ID column options.
909
- * @returns {{down: (table: import("../migration/index.js").default) => Promise<void>, up: (table: import("../migration/index.js").default) => Promise<void>}}
926
+ * @returns {{down: (table: import("../migration/index.js").default) => Promise<void>, up: (table: import("../migration/index.js").default) => Promise<void>}} - Up/down callbacks for the shared audit tables.
910
927
  */
911
928
  function createSharedAuditTablesMigration(options = {}) {
912
929
  const opts = /** @type {{id?: {type: string}}} */ (options)
@@ -2688,7 +2688,7 @@ class VelociousDatabaseRecord {
2688
2688
  * @param {string} name - Lock name (for the error message).
2689
2689
  * @param {() => Promise<T>} callback - Callback holding the lock.
2690
2690
  * @param {number | null} [holdTimeoutMs] - Max hold time; falsy disables the timeout.
2691
- * @returns {Promise<T>}
2691
+ * @returns {Promise<T>} - Callback result after the lock-protected operation.
2692
2692
  */
2693
2693
  static async runWithAdvisoryLockHoldTimeout(name, callback, holdTimeoutMs) {
2694
2694
  return await AdvisoryLockRunner.runWithAdvisoryLockHoldTimeout(name, callback, holdTimeoutMs)
@@ -3816,7 +3816,7 @@ class VelociousDatabaseRecord {
3816
3816
  * column of the same name. Returns the attached number, or 0 when
3817
3817
  * `.withCount(...)` wasn't requested for this attribute.
3818
3818
  * @param {string} attributeName - Attribute name, e.g. `"tasksCount"` or a custom `"activeMembersCount"` from `.withCount({activeMembersCount: {...}})`.
3819
- * @returns {number}
3819
+ * @returns {number} - Attached association count, or zero when absent.
3820
3820
  */
3821
3821
  readCount(attributeName) {
3822
3822
  return readPayloadAssociationCount(/** @type {import("../../record-payload-values.js").RecordPayloadValuesTarget} */ (/** @type {?} */ (this)), attributeName)
@@ -3837,7 +3837,7 @@ class VelociousDatabaseRecord {
3837
3837
  * All attached association counts as a plain object. Used by the
3838
3838
  * frontend-model serializer to ship counts alongside the record
3839
3839
  * attributes on the wire.
3840
- * @returns {Record<string, number>}
3840
+ * @returns {Record<string, number>} - Association counts keyed by attribute name.
3841
3841
  */
3842
3842
  associationCounts() {
3843
3843
  /**
@@ -3864,7 +3864,7 @@ class VelociousDatabaseRecord {
3864
3864
  * registered fn for this record (e.g. no child rows matched the
3865
3865
  * aggregate).
3866
3866
  * @param {string} name - queryData attribute name (matches a SELECT alias from the registered fn).
3867
- * @returns {?}
3867
+ * @returns {?} - Attached query-data value.
3868
3868
  */
3869
3869
  queryData(name) {
3870
3870
  return readPayloadQueryData(/** @type {import("../../record-payload-values.js").RecordPayloadValuesTarget} */ (/** @type {?} */ (this)), name)
@@ -3886,7 +3886,7 @@ class VelociousDatabaseRecord {
3886
3886
  * All attached queryData values as a plain object. Used by the
3887
3887
  * frontend-model serializer to ship queryData alongside the record
3888
3888
  * attributes on the wire.
3889
- * @returns {Record<string, ?>}
3889
+ * @returns {Record<string, ?>} - Query-data values keyed by name.
3890
3890
  */
3891
3891
  queryDataValues() {
3892
3892
  /**
@@ -3914,7 +3914,7 @@ class VelociousDatabaseRecord {
3914
3914
  * `record.can("update")` without first checking whether the ability
3915
3915
  * was loaded.
3916
3916
  * @param {string} action - Ability action name, e.g. `"update"`.
3917
- * @returns {boolean}
3917
+ * @returns {boolean} - Whether the requested ability is allowed.
3918
3918
  */
3919
3919
  can(action) {
3920
3920
  return readPayloadComputedAbility(/** @type {import("../../record-payload-values.js").RecordPayloadValuesTarget} */ (/** @type {?} */ (this)), action)
@@ -3936,7 +3936,7 @@ class VelociousDatabaseRecord {
3936
3936
  * All attached per-record ability results as a plain object. Used
3937
3937
  * by the frontend-model serializer to ship results alongside the
3938
3938
  * record attributes on the wire.
3939
- * @returns {Record<string, boolean>}
3939
+ * @returns {Record<string, boolean>} - Ability results keyed by action.
3940
3940
  */
3941
3941
  computedAbilities() {
3942
3942
  /**
@@ -74,9 +74,9 @@ export default class VelociousDatabaseRecordValidatorsUniqueness extends Base {
74
74
  * `new Task({project})`, the FK (`projectId`) is only flushed onto
75
75
  * the attribute store during save — but the relationship object is
76
76
  * already loaded and carries the id we need for the WHERE clause.
77
- * @param {import("../index.js").default} model
77
+ * @param {import("../index.js").default} model - Record whose loaded relationship may supply the scope value.
78
78
  * @param {string} scopeColumn - camelCase attribute name (e.g. `"projectId"`).
79
- * @returns {string | number | null}
79
+ * @returns {string | number | null} - Value normalized for comparison.
80
80
  */
81
81
  _resolveScopeValueFromRelationship(model, scopeColumn) {
82
82
  const modelClass = /** @type {typeof import("../index.js").default} */ (model.constructor)
@@ -106,7 +106,7 @@ export default class VelociousDatabaseRecordValidatorsUniqueness extends Base {
106
106
  * Normalize the `scope` option into an array of attribute names.
107
107
  * Supports string (`"userId"`), array of strings (`["userId", "projectId"]`),
108
108
  * or absent (empty array — no scope, original single-column behavior).
109
- * @returns {string[]}
109
+ * @returns {string[]} - Columns participating in the uniqueness check.
110
110
  */
111
111
  _normalizeScopeColumns() {
112
112
  const scope = this.args?.scope
@@ -6,9 +6,9 @@ const DEFAULT_QUERY_CHUNK_SIZE = 500
6
6
  /**
7
7
  * Splits an array into chunks of at most `chunkSize` items.
8
8
  * @template T
9
- * @param {T[]} values
10
- * @param {number} chunkSize
11
- * @returns {T[][]}
9
+ * @param {T[]} values - Ordered items to partition.
10
+ * @param {number} chunkSize - Maximum items per chunk.
11
+ * @returns {T[][]} - Consecutive chunks preserving input order.
12
12
  */
13
13
  function chunks(values, chunkSize) {
14
14
  const chunkedValues = []
@@ -22,8 +22,8 @@ function chunks(values, chunkSize) {
22
22
 
23
23
  /**
24
24
  * Stringifies values and returns the distinct, non-blank ones, preserving first-seen order.
25
- * @param {unknown[]} values
26
- * @returns {string[]}
25
+ * @param {unknown[]} values - Candidate database identifiers to stringify and deduplicate.
26
+ * @returns {string[]} - Distinct non-blank identifiers in first-seen order.
27
27
  */
28
28
  function uniqueStrings(values) {
29
29
  return Array.from(new Set(values.map((value) => String(value)).filter((value) => value.trim())))
@@ -60,7 +60,7 @@ export default class DataCopier {
60
60
  * insertChunkSize?: number,
61
61
  * queryChunkSize?: number,
62
62
  * onProgress?: (message: string) => void
63
- * }} args
63
+ * }} args - Source, target, traversal plan, chunk limits, and progress handler.
64
64
  */
65
65
  constructor({sourceDb, targetDb, tablePlan, idColumn = "id", insertChunkSize = DEFAULT_INSERT_CHUNK_SIZE, queryChunkSize = DEFAULT_QUERY_CHUNK_SIZE, onProgress}) {
66
66
  this.sourceDb = sourceDb
@@ -77,8 +77,8 @@ export default class DataCopier {
77
77
  * returns the copied source rows keyed by table name. The target's current tenant rows
78
78
  * are deleted (children first) and the source rows inserted (parents first) in a single
79
79
  * target transaction with foreign keys disabled.
80
- * @param {string} keyValue
81
- * @returns {Promise<Map<string, Record<string, unknown>[]>>}
80
+ * @param {string} keyValue - Tenant key selecting the rows to copy.
81
+ * @returns {Promise<Map<string, Record<string, unknown>[]>>} - Copied source rows grouped by table name.
82
82
  */
83
83
  async copy(keyValue) {
84
84
  const sourceRowsByTableName = await this.loadRows(this.sourceDb, keyValue)
@@ -125,9 +125,9 @@ export default class DataCopier {
125
125
  * Loads the rows for `keyValue` for every table in the plan from `db`, resolving
126
126
  * parent-scoped tables from the ids already selected for their parent table. Used for
127
127
  * both the source rows to copy and the target's current tenant rows to delete.
128
- * @param {import("../drivers/base.js").default} db
129
- * @param {string} keyValue
130
- * @returns {Promise<Map<string, Record<string, unknown>[]>>}
128
+ * @param {import("../drivers/base.js").default} db - Source or target database to traverse.
129
+ * @param {string} keyValue - Tenant key selecting the root plan rows.
130
+ * @returns {Promise<Map<string, Record<string, unknown>[]>>} - Loaded rows grouped by table name.
131
131
  */
132
132
  async loadRows(db, keyValue) {
133
133
  /** @type {Map<string, string[]>} */
@@ -175,8 +175,8 @@ export default class DataCopier {
175
175
 
176
176
  /**
177
177
  * Selects all rows of `tableName` in `db` whose `columnName` is in `values`, chunked.
178
- * @param {{columnName: string, db: import("../drivers/base.js").default, tableName: string, values: string[]}} args
179
- * @returns {Promise<Record<string, unknown>[]>}
178
+ * @param {{columnName: string, db: import("../drivers/base.js").default, tableName: string, values: string[]}} args - Table, column, database, and values for the chunked lookup.
179
+ * @returns {Promise<Record<string, unknown>[]>} - Rows matching the supplied column values.
180
180
  */
181
181
  async queryRowsByColumn({columnName, db, tableName, values}) {
182
182
  const normalizedValues = uniqueStrings(values)
@@ -201,7 +201,7 @@ export default class DataCopier {
201
201
  /**
202
202
  * Deletes the matching target rows for every plan table, children before parents, so the
203
203
  * reinsert that follows starts from a clean slate without violating foreign keys.
204
- * @param {Map<string, Record<string, unknown>[]>} rowsByTableName
204
+ * @param {Map<string, Record<string, unknown>[]>} rowsByTableName - Rows grouped by table name.
205
205
  * @returns {Promise<void>}
206
206
  */
207
207
  async deleteTargetRows(rowsByTableName) {
@@ -227,7 +227,7 @@ export default class DataCopier {
227
227
  /**
228
228
  * Inserts the loaded source rows into the target for every plan table, parents before
229
229
  * children, chunked to bound statement size.
230
- * @param {Map<string, Record<string, unknown>[]>} rowsByTableName
230
+ * @param {Map<string, Record<string, unknown>[]>} rowsByTableName - Rows grouped by table name.
231
231
  * @returns {Promise<void>}
232
232
  */
233
233
  async insertTargetRows(rowsByTableName) {
@@ -256,9 +256,9 @@ export default class DataCopier {
256
256
 
257
257
  /**
258
258
  * Quotes and comma-joins values for an SQL `IN (...)` list against the given database.
259
- * @param {import("../drivers/base.js").default} db
260
- * @param {string[]} values
261
- * @returns {string}
259
+ * @param {import("../drivers/base.js").default} db - Database whose quoting rules format the values.
260
+ * @param {string[]} values - Values to quote for the `IN` list.
261
+ * @returns {string} - Quoted SQL value list.
262
262
  */
263
263
  quotedValuesSql(db, values) {
264
264
  return values.map((value) => db.quote(value)).join(", ")
@@ -266,9 +266,9 @@ export default class DataCopier {
266
266
 
267
267
  /**
268
268
  * Runs a query without per-query logging, used for the high-volume copy statements.
269
- * @param {import("../drivers/base.js").default} db
270
- * @param {string} sql
271
- * @returns {Promise<Record<string, unknown>[]>}
269
+ * @param {import("../drivers/base.js").default} db - Database on which to execute the copy query.
270
+ * @param {string} sql - Copy-related SQL statement to execute quietly.
271
+ * @returns {Promise<Record<string, unknown>[]>} - Query result rows.
272
272
  */
273
273
  async executeQuietQuery(db, sql) {
274
274
  return await db.query(sql, {logQuery: false})
@@ -276,7 +276,7 @@ export default class DataCopier {
276
276
 
277
277
  /**
278
278
  * Inserts column-aligned row tuples into a table without per-query logging.
279
- * @param {{columns: string[], db: import("../drivers/base.js").default, rows: Array<Array<unknown>>, tableName: string}} args
279
+ * @param {{columns: string[], db: import("../drivers/base.js").default, rows: Array<Array<unknown>>, tableName: string}} args - Destination table and column-aligned row values to insert.
280
280
  * @returns {Promise<void>}
281
281
  */
282
282
  async insertRowsQuietly({columns, db, rows, tableName}) {
@@ -285,7 +285,7 @@ export default class DataCopier {
285
285
 
286
286
  /**
287
287
  * Forwards a progress message to the optional `onProgress` callback when one was given.
288
- * @param {string} message
288
+ * @param {string} message - Copy progress message to forward when reporting is enabled.
289
289
  * @returns {void}
290
290
  */
291
291
  reportProgress(message) {
@@ -31,7 +31,7 @@ const TEXT_TYPE_RANKS = {
31
31
  export default class SchemaCloner {
32
32
  /**
33
33
  * Creates a cloner that copies table structure from `sourceDb` into `targetDb`.
34
- * @param {{sourceDb: import("../drivers/base.js").default, targetDb: import("../drivers/base.js").default}} args
34
+ * @param {{sourceDb: import("../drivers/base.js").default, targetDb: import("../drivers/base.js").default}} args - Databases to clone structure from and into.
35
35
  */
36
36
  constructor({sourceDb, targetDb}) {
37
37
  this.sourceDb = sourceDb
@@ -41,7 +41,7 @@ export default class SchemaCloner {
41
41
  /**
42
42
  * Clones every given table from the source into the target, then baselines the
43
43
  * target's ledger so the cloned schema is recorded as already-migrated.
44
- * @param {string[]} tableNames
44
+ * @param {string[]} tableNames - Source tables whose structure should be cloned.
45
45
  * @returns {Promise<void>}
46
46
  */
47
47
  async syncTables(tableNames) {
@@ -55,7 +55,7 @@ export default class SchemaCloner {
55
55
  /**
56
56
  * Clones a single table from the source into the target, creating it or adding and
57
57
  * widening columns and indexes as needed.
58
- * @param {string} tableName
58
+ * @param {string} tableName - Source table to synchronize with the target.
59
59
  * @returns {Promise<void>}
60
60
  */
61
61
  async syncTable(tableName) {
@@ -82,7 +82,7 @@ export default class SchemaCloner {
82
82
  /**
83
83
  * Creates the table in the target from the source table's columns and its
84
84
  * non-primary-key indexes.
85
- * @param {{sourceTable: import("../drivers/base-table.js").default, tableName: string}} args
85
+ * @param {{sourceTable: import("../drivers/base-table.js").default, tableName: string}} args - Source table metadata and target table name.
86
86
  * @returns {Promise<void>}
87
87
  */
88
88
  async createTargetTable({sourceTable, tableName}) {
@@ -105,7 +105,7 @@ export default class SchemaCloner {
105
105
  /**
106
106
  * Adds columns present on the source but missing from the target, and widens
107
107
  * too-narrow target text columns.
108
- * @param {{sourceTable: import("../drivers/base-table.js").default, tableName: string}} args
108
+ * @param {{sourceTable: import("../drivers/base-table.js").default, tableName: string}} args - Source table metadata and target table name.
109
109
  * @returns {Promise<boolean>} Whether any column was added or widened.
110
110
  */
111
111
  async ensureTargetColumns({sourceTable, tableName}) {
@@ -154,7 +154,7 @@ export default class SchemaCloner {
154
154
  * Creates non-primary-key indexes present on the source but missing from the target,
155
155
  * and replaces target indexes whose definition (columns or uniqueness) drifted from
156
156
  * the source.
157
- * @param {{sourceTable: import("../drivers/base-table.js").default, tableName: string}} args
157
+ * @param {{sourceTable: import("../drivers/base-table.js").default, tableName: string}} args - Source table metadata and target table name.
158
158
  * @returns {Promise<void>}
159
159
  */
160
160
  async ensureTargetIndexes({sourceTable, tableName}) {
@@ -230,7 +230,7 @@ export default class SchemaCloner {
230
230
 
231
231
  /**
232
232
  * Drops an index on the target database.
233
- * @param {{tableName: string, targetIndex: import("../drivers/base-columns-index.js").default}} args
233
+ * @param {{tableName: string, targetIndex: import("../drivers/base-columns-index.js").default}} args - Target table and index to remove.
234
234
  * @returns {Promise<void>}
235
235
  */
236
236
  async dropTargetIndex({tableName, targetIndex}) {
@@ -252,7 +252,7 @@ export default class SchemaCloner {
252
252
  /**
253
253
  * Whether the target ledger is missing any version applied on the source — i.e. the
254
254
  * target schema may have been advanced out of band without recording it.
255
- * @returns {Promise<boolean>}
255
+ * @returns {Promise<boolean>} - Whether the target ledger differs from the source.
256
256
  */
257
257
  async ledgerDriftsFromSource() {
258
258
  if (!await MigrationsLedger.tableExists(this.targetDb)) {
@@ -268,8 +268,8 @@ export default class SchemaCloner {
268
268
  /**
269
269
  * Maps a source index into a TableData index for table creation (SQLite omits the
270
270
  * index name so the driver can generate a unique one).
271
- * @param {import("../drivers/base-columns-index.js").default} sourceIndex
272
- * @returns {TableIndex}
271
+ * @param {import("../drivers/base-columns-index.js").default} sourceIndex - Source index definition.
272
+ * @returns {TableIndex} - Framework-independent index definition.
273
273
  */
274
274
  tableDataIndexFromSourceIndex(sourceIndex) {
275
275
  /** @type {{name?: string, unique: boolean}} */
@@ -289,8 +289,8 @@ export default class SchemaCloner {
289
289
  /**
290
290
  * Builds driver create-index args from a source index (the index name is omitted on
291
291
  * SQLite, where index names are unique per-database rather than per-table).
292
- * @param {{sourceIndex: import("../drivers/base-columns-index.js").default, tableName: string}} args
293
- * @returns {{columns: string[], name?: string, tableName: string, unique: boolean}}
292
+ * @param {{sourceIndex: import("../drivers/base-columns-index.js").default, tableName: string}} args - Source index and target table receiving it.
293
+ * @returns {{columns: string[], name?: string, tableName: string, unique: boolean}} - Arguments for creating the target index.
294
294
  */
295
295
  createIndexArgsFromSourceIndex({sourceIndex, tableName}) {
296
296
  /** @type {{columns: string[], name?: string, tableName: string, unique: boolean}} */
@@ -309,9 +309,9 @@ export default class SchemaCloner {
309
309
 
310
310
  /**
311
311
  * Whether two indexes have the same uniqueness and ordered column list.
312
- * @param {import("../drivers/base-columns-index.js").default} sourceIndex
313
- * @param {import("../drivers/base-columns-index.js").default} targetIndex
314
- * @returns {boolean}
312
+ * @param {import("../drivers/base-columns-index.js").default} sourceIndex - Source index definition.
313
+ * @param {import("../drivers/base-columns-index.js").default} targetIndex - Target index definition.
314
+ * @returns {boolean} - Whether both indexes have the same shape.
315
315
  */
316
316
  indexesMatch(sourceIndex, targetIndex) {
317
317
  const sourceColumnNames = sourceIndex.getColumnNames()
@@ -336,8 +336,8 @@ export default class SchemaCloner {
336
336
 
337
337
  /**
338
338
  * A stable signature for an index, used to match cloned indexes by shape.
339
- * @param {import("../drivers/base-columns-index.js").default} index
340
- * @returns {string}
339
+ * @param {import("../drivers/base-columns-index.js").default} index - Index definition.
340
+ * @returns {string} - Stable index-shape signature.
341
341
  */
342
342
  indexSignature(index) {
343
343
  return `${index.isUnique() ? "unique" : "index"}:${index.getColumnNames().join(",")}`
@@ -345,8 +345,8 @@ export default class SchemaCloner {
345
345
 
346
346
  /**
347
347
  * Normalizes a column type to its canonical lowercase form (`int` becomes `integer`).
348
- * @param {string} columnType
349
- * @returns {string}
348
+ * @param {string} columnType - Database column type.
349
+ * @returns {string} - Canonical lowercase column type.
350
350
  */
351
351
  normalizedColumnType(columnType) {
352
352
  const normalizedType = columnType.toLowerCase()
@@ -360,8 +360,8 @@ export default class SchemaCloner {
360
360
 
361
361
  /**
362
362
  * The widening rank of a text column type (0 when not a text type).
363
- * @param {string} columnType
364
- * @returns {number}
363
+ * @param {string} columnType - Database column type.
364
+ * @returns {number} - Text-type widening rank.
365
365
  */
366
366
  textTypeRank(columnType) {
367
367
  return TEXT_TYPE_RANKS[this.normalizedColumnType(columnType)] || 0
@@ -369,9 +369,9 @@ export default class SchemaCloner {
369
369
 
370
370
  /**
371
371
  * Whether the target's text column is narrower than the source's and must be widened.
372
- * @param {import("../drivers/base-column.js").default} sourceColumn
373
- * @param {import("../drivers/base-column.js").default} targetColumn
374
- * @returns {boolean}
372
+ * @param {import("../drivers/base-column.js").default} sourceColumn - Source column definition.
373
+ * @param {import("../drivers/base-column.js").default} targetColumn - Target column definition.
374
+ * @returns {boolean} - Whether the target text column must be widened.
375
375
  */
376
376
  columnNeedsWidening(sourceColumn, targetColumn) {
377
377
  const sourceRank = this.textTypeRank(sourceColumn.getType())
@@ -383,9 +383,9 @@ export default class SchemaCloner {
383
383
  /**
384
384
  * Builds TableData column args from a source column, copying type, nullability,
385
385
  * length, notes, simple defaults and (for full clones) primary-key flag.
386
- * @param {import("../drivers/base-column.js").default} sourceColumn
387
- * @param {{isNewColumn: boolean}} args
388
- * @returns {Record<string, unknown>}
386
+ * @param {import("../drivers/base-column.js").default} sourceColumn - Source column definition.
387
+ * @param {{isNewColumn: boolean}} args - Whether the column is being added instead of cloned with its table.
388
+ * @returns {Record<string, unknown>} - Arguments for altering the target column.
389
389
  */
390
390
  columnArgsFromSourceColumn(sourceColumn, {isNewColumn}) {
391
391
  /** @type {{autoIncrement?: boolean, default?: unknown, isNewColumn: boolean, maxLength?: number, notes?: string, null: boolean, primaryKey?: boolean, type: string}} */
@@ -290,7 +290,6 @@ export default class VelociousEnvironmentsHandlerBrowser extends Base {
290
290
  * Runs after migrations.
291
291
  * @param {object} args - Options object.
292
292
  * @param {Record<string, import("../database/drivers/base.js").default>} args.dbs - Dbs.
293
- * @param {"migration" | "schemaDump"} [args.reason] - Why the structure hook is running.
294
293
  * @returns {Promise<void>} - Resolves when complete.
295
294
  */
296
295
  async afterMigrations({dbs}) {
@@ -19,6 +19,7 @@ export default class BackgroundJobsRunnerCommand extends BaseCommand {
19
19
  const decoded = Buffer.from(payload, "base64").toString("utf8")
20
20
  const jobPayload = JSON.parse(decoded)
21
21
 
22
- await runJobPayload(jobPayload)
22
+ await runJobPayload(jobPayload, {closeConnections: false})
23
+ process.exit(0)
23
24
  }
24
25
  }
@@ -124,7 +124,7 @@ export default class VelociousCliCommandsLintRelationships extends BaseCommand {
124
124
 
125
125
  if (!stats.isDirectory()) return false
126
126
  } catch (error) {
127
- if (/** @type {NodeJS.ErrnoException} */ (error).code == "ENOENT") return false
127
+ if (/** @type {Error & {code?: string}} */ (error).code == "ENOENT") return false
128
128
 
129
129
  throw error
130
130
  }
@@ -213,7 +213,7 @@ export default class VelociousCliCommandsLintRelationships extends BaseCommand {
213
213
  try {
214
214
  configContent = await fs.readFile(configPath, "utf8")
215
215
  } catch (error) {
216
- if (!explicitConfigPath && /** @type {NodeJS.ErrnoException} */ (error).code == "ENOENT") {
216
+ if (!explicitConfigPath && /** @type {Error & {code?: string}} */ (error).code == "ENOENT") {
217
217
  return new Set()
218
218
  }
219
219
 
@@ -860,7 +860,7 @@ export default class VelociousEnvironmentHandlerNode extends Base{
860
860
  files.push({file, fullPath, date, migrationClassName})
861
861
  }
862
862
  } catch (error) {
863
- if (/** @type {NodeJS.ErrnoException} */ (error)?.code !== "ENOENT") {
863
+ if (/** @type {Error & {code?: string}} */ (error)?.code !== "ENOENT") {
864
864
  throw error
865
865
  }
866
866
  }