velocious 1.0.633 → 1.0.635

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 (50) hide show
  1. package/README.md +21 -1
  2. package/build/background-jobs/lifecycle-client.js +1 -1
  3. package/build/background-jobs/lifecycle-control-server.js +1 -1
  4. package/build/background-jobs/main.js +9 -3
  5. package/build/cli/commands/db/migrate.js +3 -1
  6. package/build/cli/commands/db/tenants/migrate.js +4 -1
  7. package/build/cli/commands/db/tenants/migrations/pending.js +4 -1
  8. package/build/cli/index.js +1 -1
  9. package/build/cli/migration-execution-phase-argument.js +20 -0
  10. package/build/database/migration/index.js +21 -0
  11. package/build/database/migration-execution-phase.js +34 -0
  12. package/build/database/migrator.js +6 -1
  13. package/build/src/background-jobs/lifecycle-client.d.ts +1 -1
  14. package/build/src/background-jobs/lifecycle-client.d.ts.map +1 -1
  15. package/build/src/background-jobs/lifecycle-client.js +2 -2
  16. package/build/src/background-jobs/lifecycle-control-server.js +2 -2
  17. package/build/src/background-jobs/main.d.ts.map +1 -1
  18. package/build/src/background-jobs/main.js +11 -4
  19. package/build/src/cli/commands/db/migrate.d.ts.map +1 -1
  20. package/build/src/cli/commands/db/migrate.js +4 -2
  21. package/build/src/cli/commands/db/tenants/migrate.d.ts.map +1 -1
  22. package/build/src/cli/commands/db/tenants/migrate.js +5 -2
  23. package/build/src/cli/commands/db/tenants/migrations/pending.d.ts.map +1 -1
  24. package/build/src/cli/commands/db/tenants/migrations/pending.js +5 -2
  25. package/build/src/cli/index.js +2 -2
  26. package/build/src/cli/migration-execution-phase-argument.d.ts +7 -0
  27. package/build/src/cli/migration-execution-phase-argument.d.ts.map +1 -0
  28. package/build/src/cli/migration-execution-phase-argument.js +17 -0
  29. package/build/src/database/migration/index.d.ts +13 -0
  30. package/build/src/database/migration/index.d.ts.map +1 -1
  31. package/build/src/database/migration/index.js +19 -1
  32. package/build/src/database/migration-execution-phase.d.ts +18 -0
  33. package/build/src/database/migration-execution-phase.d.ts.map +1 -0
  34. package/build/src/database/migration-execution-phase.js +30 -0
  35. package/build/src/database/migrator.d.ts +4 -1
  36. package/build/src/database/migrator.d.ts.map +1 -1
  37. package/build/src/database/migrator.js +9 -2
  38. package/build/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +1 -1
  40. package/src/background-jobs/lifecycle-client.js +1 -1
  41. package/src/background-jobs/lifecycle-control-server.js +1 -1
  42. package/src/background-jobs/main.js +9 -3
  43. package/src/cli/commands/db/migrate.js +3 -1
  44. package/src/cli/commands/db/tenants/migrate.js +4 -1
  45. package/src/cli/commands/db/tenants/migrations/pending.js +4 -1
  46. package/src/cli/index.js +1 -1
  47. package/src/cli/migration-execution-phase-argument.js +20 -0
  48. package/src/database/migration/index.js +21 -0
  49. package/src/database/migration-execution-phase.js +34 -0
  50. package/src/database/migrator.js +6 -1
@@ -602,10 +602,14 @@ export default class BackgroundJobsMain {
602
602
  * @returns {Promise<void>} - Activation completion.
603
603
  */
604
604
  async _activate() {
605
+ this.logger.info(() => ["Background jobs generation activation starting", {generationId: this.generationId}])
605
606
  await this._startActiveOwnership()
606
607
  this.lifecycleState = "active"
607
608
  this._creditReadyWorkers()
608
- await this._drain()
609
+ this.logger.info(() => ["Background jobs generation activation acknowledged", {generationId: this.generationId}])
610
+ void this._drain().catch((error) => {
611
+ this.logger.error(() => ["Background jobs generation post-activation drain failed", {error, generationId: this.generationId}])
612
+ })
609
613
  }
610
614
 
611
615
  /**
@@ -614,7 +618,7 @@ export default class BackgroundJobsMain {
614
618
  */
615
619
  retire() {
616
620
  if (!this.generationId) throw new Error("Background jobs generation retirement requires generation mode")
617
- if (this.lifecycleState === "retiring" || this.lifecycleState === "retired") return this._retirementPromise || Promise.resolve()
621
+ if (this.lifecycleState === "retiring" || this.lifecycleState === "retired") return Promise.resolve()
618
622
  if (this.lifecycleState !== "active") throw new Error(`Cannot retire background jobs generation from ${this.lifecycleState}`)
619
623
 
620
624
  this.lifecycleState = "retiring"
@@ -624,8 +628,9 @@ export default class BackgroundJobsMain {
624
628
  this._clearDispatchTimers()
625
629
  this._disconnectBeaconHandlers()
626
630
  this._retirementPromise = this._retire()
631
+ void this._retirementPromise.catch((error) => this._reportConnectionHandlerError(error))
627
632
 
628
- return this._retirementPromise
633
+ return Promise.resolve()
629
634
  }
630
635
 
631
636
  /**
@@ -636,6 +641,7 @@ export default class BackgroundJobsMain {
636
641
  await this.scheduler?.stop()
637
642
  this.scheduler = undefined
638
643
  if (this._drainPromise) await this._drainPromise
644
+ if (this._stopped) return
639
645
 
640
646
  for (const worker of this.workers) {
641
647
  worker.isDraining = true
@@ -1,11 +1,13 @@
1
1
  import BaseCommand from "../../base-command.js"
2
2
  import {digg} from "diggerize"
3
3
  import Migrator from "../../../database/migrator.js"
4
+ import migrationExecutionPhaseArgument from "../../migration-execution-phase-argument.js"
4
5
 
5
6
  export default class DbMigrate extends BaseCommand {
6
7
  async execute() {
8
+ const executionPhase = migrationExecutionPhaseArgument(this.processArgs || [])
7
9
  const migrations = await this.getEnvironmentHandler().findMigrations()
8
- const migrator = new Migrator({configuration: this.getConfiguration()})
10
+ const migrator = new Migrator({configuration: this.getConfiguration(), executionPhase})
9
11
 
10
12
  console.log(`Running ${migrations.length} migrations`)
11
13
 
@@ -4,6 +4,7 @@ import {digg} from "diggerize"
4
4
  import BaseCommand from "../../../base-command.js"
5
5
  import Migrator from "../../../../database/migrator.js"
6
6
  import TenantDatabaseCommandHelper from "../../../tenant-database-command-helper.js"
7
+ import migrationExecutionPhaseArgument from "../../../migration-execution-phase-argument.js"
7
8
 
8
9
  export default class DbTenantsMigrate extends BaseCommand {
9
10
  /**
@@ -11,6 +12,7 @@ export default class DbTenantsMigrate extends BaseCommand {
11
12
  * @returns {Promise<{identifier: string, migrationCount: number, tenantCount: number} | void>} - Result in test mode.
12
13
  */
13
14
  async execute() {
15
+ const executionPhase = migrationExecutionPhaseArgument(this.processArgs || [])
14
16
  const helper = new TenantDatabaseCommandHelper({
15
17
  command: this,
16
18
  identifier: this.processArgs?.[1]
@@ -19,7 +21,8 @@ export default class DbTenantsMigrate extends BaseCommand {
19
21
  const tenantCount = await helper.eachTenant(async ({databaseConfiguration, tenant}) => {
20
22
  const migrator = new Migrator({
21
23
  configuration: this.getConfiguration(),
22
- databaseIdentifiers: [helper.identifier]
24
+ databaseIdentifiers: [helper.identifier],
25
+ executionPhase
23
26
  })
24
27
 
25
28
  let migrationsApplied = 0
@@ -4,6 +4,8 @@ import {digg} from "diggerize"
4
4
  import BaseCommand from "../../../../base-command.js"
5
5
  import TenantDatabaseCommandHelper from "../../../../tenant-database-command-helper.js"
6
6
  import TenantMigrationPendingInspector from "../../../../../database/tenants/migration-pending-inspector.js"
7
+ import { migrationRunsInExecutionPhase } from "../../../../../database/migration-execution-phase.js"
8
+ import migrationExecutionPhaseArgument from "../../../../migration-execution-phase-argument.js"
7
9
 
8
10
  export default class DbTenantsMigrationsPending extends BaseCommand {
9
11
  /**
@@ -11,6 +13,7 @@ export default class DbTenantsMigrationsPending extends BaseCommand {
11
13
  * @returns {Promise<{hasPendingMigrations: boolean, identifier: string, migrationCount: number, pendingTenantCount: number, tenantCount: number}>} - Deploy preflight result.
12
14
  */
13
15
  async execute() {
16
+ const executionPhase = migrationExecutionPhaseArgument(this.processArgs || [])
14
17
  const helper = new TenantDatabaseCommandHelper({
15
18
  command: this,
16
19
  identifier: this.processArgs?.[1]
@@ -24,7 +27,7 @@ export default class DbTenantsMigrationsPending extends BaseCommand {
24
27
 
25
28
  const MigrationClass = await requireMigration(migration.fullPath)
26
29
 
27
- if ((MigrationClass.getDatabaseIdentifiers() || ["default"]).includes(helper.identifier)) {
30
+ if (migrationRunsInExecutionPhase(MigrationClass, executionPhase) && (MigrationClass.getDatabaseIdentifiers() || ["default"]).includes(helper.identifier)) {
28
31
  applicableMigrationVersions.push(migration.date)
29
32
  }
30
33
  }
package/src/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @ts-check
2
2
 
3
- const COMMAND_VALUE_OPTIONS = new Set(["--generation", "--initial-generation-state", "--lifecycle-socket", "--socket", "--tenant"])
3
+ const COMMAND_VALUE_OPTIONS = new Set(["--generation", "--initial-generation-state", "--lifecycle-socket", "--phase", "--socket", "--tenant"])
4
4
 
5
5
  export default class VelociousCli {
6
6
  /**
@@ -0,0 +1,20 @@
1
+ // @ts-check
2
+
3
+ import { migrationExecutionPhase } from "../database/migration-execution-phase.js"
4
+
5
+ /**
6
+ * Reads an optional `--phase` value from one command's raw arguments.
7
+ * @param {string[]} processArgs - Raw command arguments including the command name.
8
+ * @returns {import("../database/migration-execution-phase.js").MigrationExecutionPhase | undefined} - Selected phase.
9
+ */
10
+ export default function migrationExecutionPhaseArgument(processArgs) {
11
+ const phaseArgumentIndex = processArgs.indexOf("--phase")
12
+
13
+ if (phaseArgumentIndex < 0) return undefined
14
+
15
+ const phase = processArgs[phaseArgumentIndex + 1]
16
+
17
+ if (!phase || phase.startsWith("-")) throw new Error("Missing value for --phase")
18
+
19
+ return migrationExecutionPhase(phase)
20
+ }
@@ -28,6 +28,7 @@
28
28
  import { convertLegacyDateValueToUtcStorage } from "../datetime-storage.js"
29
29
  import * as inflection from "inflection"
30
30
  import restArgsError from "../../utils/rest-args-error.js"
31
+ import { DEFAULT_MIGRATION_EXECUTION_PHASE, migrationExecutionPhase } from "../migration-execution-phase.js"
31
32
  import ChangeTable from "./change-table.js"
32
33
  import CreateIndexBase from "../query/create-index-base.js"
33
34
  import TableColumn from "../table-data/table-column.js"
@@ -38,6 +39,26 @@ class NotImplementedError extends Error {}
38
39
  export {NotImplementedError}
39
40
 
40
41
  export default class VelociousDatabaseMigration {
42
+ /** @type {import("../migration-execution-phase.js").MigrationExecutionPhase | undefined} */
43
+ static _executionPhase
44
+
45
+ /**
46
+ * Declares when this migration is eligible to run.
47
+ * @param {import("../migration-execution-phase.js").MigrationExecutionPhase} phase - Execution phase.
48
+ * @returns {void} - No return value.
49
+ */
50
+ static runInPhase(phase) {
51
+ this._executionPhase = migrationExecutionPhase(phase)
52
+ }
53
+
54
+ /**
55
+ * Gets the declared execution phase.
56
+ * @returns {import("../migration-execution-phase.js").MigrationExecutionPhase} - Declared execution phase.
57
+ */
58
+ static getExecutionPhase() {
59
+ return this._executionPhase || DEFAULT_MIGRATION_EXECUTION_PHASE
60
+ }
61
+
41
62
  /**
42
63
  * Runs on databases.
43
64
  * @param {string[]} databaseIdentifiers - Database identifiers.
@@ -0,0 +1,34 @@
1
+ // @ts-check
2
+
3
+ /** @typedef {"post-publication" | "pre-runtime"} MigrationExecutionPhase */
4
+
5
+ /** @type {MigrationExecutionPhase} */
6
+ export const DEFAULT_MIGRATION_EXECUTION_PHASE = "pre-runtime"
7
+
8
+ /**
9
+ * Validates and returns one supported migration execution phase.
10
+ * @param {string | undefined} phase - Migration execution phase.
11
+ * @returns {MigrationExecutionPhase} - Validated execution phase.
12
+ */
13
+ export function migrationExecutionPhase(phase) {
14
+ if (phase === undefined) {
15
+ throw new Error("Missing migration execution phase. Expected one of: pre-runtime, post-publication")
16
+ }
17
+ if (phase !== "pre-runtime" && phase !== "post-publication") {
18
+ throw new Error(`Unknown migration execution phase ${JSON.stringify(phase)}. Expected one of: pre-runtime, post-publication`)
19
+ }
20
+
21
+ return phase
22
+ }
23
+
24
+ /**
25
+ * Tests whether a migration class belongs to an optional selected phase.
26
+ * @param {typeof import("./migration/index.js").default} MigrationClass - Migration class.
27
+ * @param {MigrationExecutionPhase | undefined} executionPhase - Optional selected phase.
28
+ * @returns {boolean} - Whether the migration belongs to the selection.
29
+ */
30
+ export function migrationRunsInExecutionPhase(MigrationClass, executionPhase) {
31
+ if (executionPhase === undefined) return true
32
+
33
+ return MigrationClass.getExecutionPhase() === executionPhase
34
+ }
@@ -5,6 +5,7 @@ import * as inflection from "inflection"
5
5
  import Logger from "../logger.js"
6
6
  import MigrationsLedger from "./migrations-ledger.js"
7
7
  import {NotImplementedError} from "./migration/index.js"
8
+ import { migrationExecutionPhase, migrationRunsInExecutionPhase } from "./migration-execution-phase.js"
8
9
  import restArgsError from "../utils/rest-args-error.js"
9
10
 
10
11
  export default class VelociousDatabaseMigrator {
@@ -18,14 +19,16 @@ export default class VelociousDatabaseMigrator {
18
19
  * @param {object} args - Options object.
19
20
  * @param {import("../configuration.js").default} args.configuration - Configuration instance.
20
21
  * @param {string[]} [args.databaseIdentifiers] - Optional database identifiers to migrate.
22
+ * @param {import("./migration-execution-phase.js").MigrationExecutionPhase} [args.executionPhase] - Optional migration execution phase to select.
21
23
  */
22
- constructor({configuration, databaseIdentifiers, ...restArgs}) {
24
+ constructor({configuration, databaseIdentifiers, executionPhase, ...restArgs}) {
23
25
  restArgsError(restArgs)
24
26
 
25
27
  if (!configuration) throw new Error("configuration argument is required")
26
28
 
27
29
  this.configuration = configuration
28
30
  this.databaseIdentifiers = databaseIdentifiers
31
+ this.executionPhase = executionPhase === undefined ? undefined : migrationExecutionPhase(executionPhase)
29
32
  this.logger = new Logger(this)
30
33
  }
31
34
 
@@ -188,6 +191,7 @@ export default class VelociousDatabaseMigrator {
188
191
  if (!MigrationClass || typeof MigrationClass !== "function") {
189
192
  throw new Error(`Migration ${migration.file} must export a default migration class. Type: ${typeof MigrationClass}`)
190
193
  }
194
+ if (!migrationRunsInExecutionPhase(MigrationClass, this.executionPhase)) continue
191
195
  if (!(MigrationClass.getDatabaseIdentifiers() || ["default"]).includes(databaseIdentifier)) continue
192
196
 
193
197
  const migrationInstance = new MigrationClass({configuration: this.configuration, databaseIdentifier, db})
@@ -519,6 +523,7 @@ export default class VelociousDatabaseMigrator {
519
523
  if (!migrationClass || typeof migrationClass !== "function") {
520
524
  throw new Error(`Migration ${migration.file} must export a default migration class. Type: ${typeof migrationClass}`)
521
525
  }
526
+ if (direction == "up" && !migrationRunsInExecutionPhase(migrationClass, this.executionPhase)) return false
522
527
 
523
528
  const migrationDatabaseIdentifiers = migrationClass.getDatabaseIdentifiers() || ["default"]
524
529