velocious 1.0.545 → 1.0.547
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.
- package/README.md +24 -0
- package/build/background-jobs/store.js +39 -0
- package/build/database/record/index.js +1 -1
- package/build/database/tenants/data-copier.js +134 -5
- package/build/environment-handlers/node/cli/commands/generate/base-models.js +3 -1
- package/build/environment-handlers/node/cli/commands/test.js +32 -0
- package/build/src/background-jobs/store.d.ts +7 -0
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +36 -1
- package/build/src/database/record/index.js +2 -2
- package/build/src/database/tenants/data-copier.d.ts +63 -0
- package/build/src/database/tenants/data-copier.d.ts.map +1 -1
- package/build/src/database/tenants/data-copier.js +113 -5
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +3 -2
- package/build/src/environment-handlers/node/cli/commands/test.d.ts +8 -0
- package/build/src/environment-handlers/node/cli/commands/test.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/test.js +27 -1
- package/build/src/testing/test-runner.d.ts +18 -0
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +20 -1
- package/build/testing/test-runner.js +23 -0
- package/package.json +1 -1
- package/src/background-jobs/store.js +39 -0
- package/src/database/record/index.js +1 -1
- package/src/database/tenants/data-copier.js +134 -5
- package/src/environment-handlers/node/cli/commands/generate/base-models.js +3 -1
- package/src/environment-handlers/node/cli/commands/test.js +32 -0
- package/src/testing/test-runner.js +23 -0
package/README.md
CHANGED
|
@@ -119,6 +119,28 @@ it("retries a flaky check", {retry: 2}, async () => {})
|
|
|
119
119
|
})
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
+
Velocious prints the slowest tests after every run so suite hotspots are easy to spot. Each line shows the duration, full description and `file:line`.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Default: the 10 slowest tests are printed after the run summary.
|
|
126
|
+
npx velocious test
|
|
127
|
+
|
|
128
|
+
# Report the 25 slowest tests instead.
|
|
129
|
+
VELOCIOUS_SLOW_TEST_COUNT=25 npx velocious test
|
|
130
|
+
|
|
131
|
+
# Disable the report.
|
|
132
|
+
VELOCIOUS_SLOW_TEST_COUNT=0 npx velocious test
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
Slowest 10 tests:
|
|
137
|
+
1145ms Background jobs - store backfills execution modes for legacy queued jobs (spec/background-jobs/store-spec.js:984)
|
|
138
|
+
913ms Background jobs - store prunes completed rows past the retention window (spec/background-jobs/store-spec.js:825)
|
|
139
|
+
...
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The report is skipped for single-test runs. See [docs/testing-guidelines.md](docs/testing-guidelines.md).
|
|
143
|
+
|
|
122
144
|
Velocious captures console output emitted while each test executes, but does not print passing-test output by default. When a test fails, Velocious prints a truncated `Console output:` block for that failed test and saves the full captured log under `tmp/screenshots` next to failure screenshots/browser logs/HTML. Each failed test summary prints the saved console log path.
|
|
123
145
|
|
|
124
146
|
Configure console output behavior in your testing config file.
|
|
@@ -2338,4 +2360,6 @@ At runtime, the apartment-style `Tenant` façade (`velocious/build/src/tenants/t
|
|
|
2338
2360
|
|
|
2339
2361
|
`SchemaCloner` adds a missing auto-increment column and its separate source unique index in one schema alteration, including on MySQL/MariaDB where an auto-increment column must be keyed when it is created.
|
|
2340
2362
|
|
|
2363
|
+
`DataCopier.move(...)` safely re-homes selected rows between different physical databases: the target write and verification commit before the source delete, target-only row transformations are supported, and retries after the source is gone preserve the target.
|
|
2364
|
+
|
|
2341
2365
|
See [docs/tenant-databases.md](docs/tenant-databases.md) for the full configuration and migration pattern.
|
|
@@ -55,6 +55,20 @@ const SORTABLE_COLUMNS = {
|
|
|
55
55
|
scheduledAtMs: "scheduled_at_ms"
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Serializes concurrent `_applySchema` runs within THIS process, keyed by database
|
|
60
|
+
* identifier. Two stores that share one connection (SingleMultiUse / SQLite)
|
|
61
|
+
* otherwise interleave the multi-step table rebuild and corrupt it (the jobs table
|
|
62
|
+
* is left as its `*_velocious_rebuild` temp). A DB advisory lock can't fix that: on
|
|
63
|
+
* a session-scoped / re-entrant driver (MySQL `GET_LOCK`) a second acquire on the
|
|
64
|
+
* same session succeeds immediately so both callers proceed, and taking it on a
|
|
65
|
+
* separate connection blocks cross-session forever. An in-process promise-chain
|
|
66
|
+
* mutex serializes same-process callers with neither hazard. Cross-process schema
|
|
67
|
+
* races stay covered by the per-step advisory locks + rechecks inside the steps.
|
|
68
|
+
* @type {Map<string, Promise<void>>}
|
|
69
|
+
*/
|
|
70
|
+
const schemaApplyChains = new Map()
|
|
71
|
+
|
|
58
72
|
export default class BackgroundJobsStore {
|
|
59
73
|
/**
|
|
60
74
|
* Runs constructor.
|
|
@@ -804,6 +818,31 @@ export default class BackgroundJobsStore {
|
|
|
804
818
|
* @returns {Promise<void>} - Resolves when the schema is present.
|
|
805
819
|
*/
|
|
806
820
|
async _applySchema(db) {
|
|
821
|
+
// Serialize concurrent schema applies within this process, keyed by database
|
|
822
|
+
// identifier (see `schemaApplyChains`). The per-step locks inside the steps use
|
|
823
|
+
// DIFFERENT lock names, so two concurrent callers could otherwise each hold a
|
|
824
|
+
// different step lock while both rebuild the jobs table — and on SQLite/MSSQL an
|
|
825
|
+
// add-column is a create-copy-drop-rename rebuild, so overlapping rebuilds
|
|
826
|
+
// corrupt it. This mutex makes the whole apply mutually exclusive per process;
|
|
827
|
+
// the second caller then re-checks and finds every step already done.
|
|
828
|
+
const identifier = this.getDatabaseIdentifier() ?? "default"
|
|
829
|
+
const previous = schemaApplyChains.get(identifier) ?? Promise.resolve()
|
|
830
|
+
const run = previous.then(() => this._applySchemaSteps(db), () => this._applySchemaSteps(db))
|
|
831
|
+
|
|
832
|
+
// Keep the chain alive regardless of this run's outcome so one failed apply does
|
|
833
|
+
// not wedge later callers; this run still propagates its own result/error.
|
|
834
|
+
schemaApplyChains.set(identifier, run.then(() => {}, () => {}))
|
|
835
|
+
|
|
836
|
+
return await run
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Creates or upgrades the background-jobs tables, columns and concurrency rows on
|
|
841
|
+
* the given connection. Serialized per process by {@link BackgroundJobsStore#_applySchema}.
|
|
842
|
+
* @param {import("../database/drivers/base.js").default} db - Database connection.
|
|
843
|
+
* @returns {Promise<void>} - Resolves when the schema is present.
|
|
844
|
+
*/
|
|
845
|
+
async _applySchemaSteps(db) {
|
|
807
846
|
await this._ensureMigrationsTable(db)
|
|
808
847
|
|
|
809
848
|
const alreadyApplied = await this._hasMigration(db)
|
|
@@ -770,7 +770,7 @@ class VelociousDatabaseRecord {
|
|
|
770
770
|
}
|
|
771
771
|
|
|
772
772
|
prototype[`${relationshipName}OrLoad`] = async function() {
|
|
773
|
-
return await this.relationshipOrLoad(relationshipName
|
|
773
|
+
return await this.relationshipOrLoad(relationshipName)
|
|
774
774
|
}
|
|
775
775
|
|
|
776
776
|
prototype[`set${inflection.camelize(relationshipName)}`] = function(/** @type {VelociousDatabaseRecord | null | undefined} */ model) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
+
import {POOL_CONFIGURATION_KEY} from "../pool/base.js"
|
|
4
|
+
|
|
3
5
|
const DEFAULT_INSERT_CHUNK_SIZE = 100
|
|
4
6
|
const DEFAULT_QUERY_CHUNK_SIZE = 500
|
|
5
7
|
const DEFAULT_STREAM_BATCH_SIZE = 1000
|
|
@@ -95,6 +97,56 @@ export default class DataCopier {
|
|
|
95
97
|
return sourceRowsByTableName
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Moves every plan table's rows for `keyValue` from the source into the target. The target
|
|
102
|
+
* write commits before the source delete begins, so a target failure leaves the source
|
|
103
|
+
* untouched and a source-delete failure can be retried safely. When the source no longer has
|
|
104
|
+
* matching rows, the method returns the empty traversal without changing the target.
|
|
105
|
+
*
|
|
106
|
+
* `transformRow` can change target-only values such as a tenant ownership column. It receives
|
|
107
|
+
* a shallow clone and must preserve the configured id column so retries address the same rows.
|
|
108
|
+
* @param {string} keyValue - Tenant key selecting the rows to move.
|
|
109
|
+
* @param {{transformRow?: (args: {row: Record<string, unknown>, tableName: string}) => Record<string, unknown>}} [options] - Optional target-row transformation.
|
|
110
|
+
* @returns {Promise<Map<string, Record<string, unknown>[]>>} - Rows written to the target, grouped by table name.
|
|
111
|
+
*/
|
|
112
|
+
async move(keyValue, {transformRow} = {}) {
|
|
113
|
+
const sourceDbWithPoolKey = /** @type {import("../drivers/base.js").default & {[POOL_CONFIGURATION_KEY]?: string}} */ (this.sourceDb)
|
|
114
|
+
const targetDbWithPoolKey = /** @type {import("../drivers/base.js").default & {[POOL_CONFIGURATION_KEY]?: string}} */ (this.targetDb)
|
|
115
|
+
const sourceReuseKey = sourceDbWithPoolKey[POOL_CONFIGURATION_KEY]
|
|
116
|
+
const targetReuseKey = targetDbWithPoolKey[POOL_CONFIGURATION_KEY]
|
|
117
|
+
const sameResolvedDatabase = this.sourceDb.configuration === this.targetDb.configuration
|
|
118
|
+
&& sourceReuseKey !== undefined
|
|
119
|
+
&& sourceReuseKey === targetReuseKey
|
|
120
|
+
|
|
121
|
+
if (this.sourceDb === this.targetDb || sameResolvedDatabase) {
|
|
122
|
+
throw new Error("DataCopier move requires different physical databases.")
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const sourceRowsByTableName = await this.loadRows(this.sourceDb, keyValue)
|
|
126
|
+
|
|
127
|
+
if (!this.rowsByTableNameHasRows(sourceRowsByTableName)) {
|
|
128
|
+
return sourceRowsByTableName
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const targetRowsByTableName = this.transformRows({rowsByTableName: sourceRowsByTableName, transformRow})
|
|
132
|
+
|
|
133
|
+
await this.targetDb.withDisabledForeignKeys(async () => {
|
|
134
|
+
await this.targetDb.transaction(async () => {
|
|
135
|
+
await this.deleteRows({db: this.targetDb, rowsByTableName: sourceRowsByTableName})
|
|
136
|
+
await this.insertRows({db: this.targetDb, rowsByTableName: targetRowsByTableName})
|
|
137
|
+
await this.assertRowsExist({db: this.targetDb, rowsByTableName: targetRowsByTableName})
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
await this.sourceDb.withDisabledForeignKeys(async () => {
|
|
142
|
+
await this.sourceDb.transaction(async () => {
|
|
143
|
+
await this.deleteRows({db: this.sourceDb, rowsByTableName: sourceRowsByTableName})
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
return targetRowsByTableName
|
|
148
|
+
}
|
|
149
|
+
|
|
98
150
|
/**
|
|
99
151
|
* Deletes one tenant's rows from the target database, children before parents, with
|
|
100
152
|
* foreign keys disabled inside a single transaction. This is `copy` without the reinsert:
|
|
@@ -409,6 +461,15 @@ export default class DataCopier {
|
|
|
409
461
|
* @returns {Promise<void>}
|
|
410
462
|
*/
|
|
411
463
|
async deleteTargetRows(rowsByTableName) {
|
|
464
|
+
await this.deleteRows({db: this.targetDb, rowsByTableName})
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Deletes the supplied rows from `db`, children before parents.
|
|
469
|
+
* @param {{db: import("../drivers/base.js").default, rowsByTableName: Map<string, Record<string, unknown>[]>}} args - Database and rows to delete.
|
|
470
|
+
* @returns {Promise<void>}
|
|
471
|
+
*/
|
|
472
|
+
async deleteRows({db, rowsByTableName}) {
|
|
412
473
|
for (const tableConfig of [...this.tablePlan].reverse()) {
|
|
413
474
|
const rowIds = uniqueStrings((rowsByTableName.get(tableConfig.tableName) || []).map((row) => row[this.idColumn]))
|
|
414
475
|
|
|
@@ -416,13 +477,13 @@ export default class DataCopier {
|
|
|
416
477
|
continue
|
|
417
478
|
}
|
|
418
479
|
|
|
419
|
-
const quotedTable =
|
|
420
|
-
const quotedIdColumn =
|
|
480
|
+
const quotedTable = db.quoteTable(tableConfig.tableName)
|
|
481
|
+
const quotedIdColumn = db.quoteColumn(this.idColumn)
|
|
421
482
|
|
|
422
483
|
for (const rowIdsChunk of chunks(rowIds, this.queryChunkSize)) {
|
|
423
484
|
await this.executeQuietQuery(
|
|
424
|
-
|
|
425
|
-
`DELETE FROM ${quotedTable} WHERE ${quotedIdColumn} IN (${this.quotedValuesSql(
|
|
485
|
+
db,
|
|
486
|
+
`DELETE FROM ${quotedTable} WHERE ${quotedIdColumn} IN (${this.quotedValuesSql(db, rowIdsChunk)})`
|
|
426
487
|
)
|
|
427
488
|
}
|
|
428
489
|
}
|
|
@@ -435,6 +496,15 @@ export default class DataCopier {
|
|
|
435
496
|
* @returns {Promise<void>}
|
|
436
497
|
*/
|
|
437
498
|
async insertTargetRows(rowsByTableName) {
|
|
499
|
+
await this.insertRows({db: this.targetDb, rowsByTableName})
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Inserts the supplied rows into `db`, parents before children.
|
|
504
|
+
* @param {{db: import("../drivers/base.js").default, rowsByTableName: Map<string, Record<string, unknown>[]>}} args - Database and rows to insert.
|
|
505
|
+
* @returns {Promise<void>}
|
|
506
|
+
*/
|
|
507
|
+
async insertRows({db, rowsByTableName}) {
|
|
438
508
|
for (const tableConfig of this.tablePlan) {
|
|
439
509
|
const rows = rowsByTableName.get(tableConfig.tableName) || []
|
|
440
510
|
|
|
@@ -450,7 +520,7 @@ export default class DataCopier {
|
|
|
450
520
|
for (const rowsChunk of insertChunks) {
|
|
451
521
|
await this.insertRowsQuietly({
|
|
452
522
|
columns,
|
|
453
|
-
db
|
|
523
|
+
db,
|
|
454
524
|
rows: rowsChunk.map((row) => columns.map((column) => row[column])),
|
|
455
525
|
tableName: tableConfig.tableName
|
|
456
526
|
})
|
|
@@ -458,6 +528,65 @@ export default class DataCopier {
|
|
|
458
528
|
}
|
|
459
529
|
}
|
|
460
530
|
|
|
531
|
+
/**
|
|
532
|
+
* Returns whether any table in the loaded traversal contains rows.
|
|
533
|
+
* @param {Map<string, Record<string, unknown>[]>} rowsByTableName - Rows grouped by table name.
|
|
534
|
+
* @returns {boolean} - Whether any table contains rows.
|
|
535
|
+
*/
|
|
536
|
+
rowsByTableNameHasRows(rowsByTableName) {
|
|
537
|
+
for (const rows of rowsByTableName.values()) {
|
|
538
|
+
if (rows.length > 0) {
|
|
539
|
+
return true
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return false
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Clones source rows and applies the optional target-only transformation.
|
|
548
|
+
* @param {{rowsByTableName: Map<string, Record<string, unknown>[]>, transformRow?: (args: {row: Record<string, unknown>, tableName: string}) => Record<string, unknown>}} args - Source rows and optional transformation.
|
|
549
|
+
* @returns {Map<string, Record<string, unknown>[]>} - Cloned rows prepared for the target.
|
|
550
|
+
*/
|
|
551
|
+
transformRows({rowsByTableName, transformRow}) {
|
|
552
|
+
const transformedRowsByTableName = new Map()
|
|
553
|
+
|
|
554
|
+
for (const tableConfig of this.tablePlan) {
|
|
555
|
+
const sourceRows = rowsByTableName.get(tableConfig.tableName) || []
|
|
556
|
+
const transformedRows = sourceRows.map((sourceRow) => {
|
|
557
|
+
const transformedRow = transformRow
|
|
558
|
+
? transformRow({row: {...sourceRow}, tableName: tableConfig.tableName})
|
|
559
|
+
: {...sourceRow}
|
|
560
|
+
|
|
561
|
+
if (String(transformedRow[this.idColumn]) !== String(sourceRow[this.idColumn])) {
|
|
562
|
+
throw new Error(`DataCopier move transform must preserve ${this.idColumn} for table ${tableConfig.tableName}.`)
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
return transformedRow
|
|
566
|
+
})
|
|
567
|
+
|
|
568
|
+
transformedRowsByTableName.set(tableConfig.tableName, transformedRows)
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return transformedRowsByTableName
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Verifies that every supplied row id exists in `db`.
|
|
576
|
+
* @param {{db: import("../drivers/base.js").default, rowsByTableName: Map<string, Record<string, unknown>[]>}} args - Database and rows to verify.
|
|
577
|
+
* @returns {Promise<void>}
|
|
578
|
+
*/
|
|
579
|
+
async assertRowsExist({db, rowsByTableName}) {
|
|
580
|
+
for (const tableConfig of this.tablePlan) {
|
|
581
|
+
const expectedIds = uniqueStrings((rowsByTableName.get(tableConfig.tableName) || []).map((row) => row[this.idColumn]))
|
|
582
|
+
const existingIds = await this.queryExistingIds({db, ids: expectedIds, tableName: tableConfig.tableName})
|
|
583
|
+
|
|
584
|
+
if (existingIds.size !== expectedIds.length) {
|
|
585
|
+
throw new Error(`DataCopier move target verification failed for table ${tableConfig.tableName}.`)
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
461
590
|
/**
|
|
462
591
|
* Quotes and comma-joins values for an SQL `IN (...)` list against the given database.
|
|
463
592
|
* @param {import("../drivers/base.js").default} db - Database whose quoting rules format the values.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import BaseCommand from "../../../../../cli/base-command.js"
|
|
2
4
|
import deburrColumnName from "../../../../../utils/deburr-column-name.js"
|
|
3
5
|
import fileExists from "../../../../../utils/file-exists.js"
|
|
@@ -339,7 +341,7 @@ export default class DbGenerateModel extends BaseCommand {
|
|
|
339
341
|
fileContent += " /**\n"
|
|
340
342
|
fileContent += ` * @returns {Promise<import("${modelFilePath}").default | undefined>}\n`
|
|
341
343
|
fileContent += " */\n"
|
|
342
|
-
fileContent += ` ${relationship.getRelationshipName()}OrLoad() { return /** @type {Promise<import("${modelFilePath}").default | undefined>} */ (this.relationshipOrLoad("${relationship.getRelationshipName()}"
|
|
344
|
+
fileContent += ` ${relationship.getRelationshipName()}OrLoad() { return /** @type {Promise<import("${modelFilePath}").default | undefined>} */ (this.relationshipOrLoad("${relationship.getRelationshipName()}")) }\n`
|
|
343
345
|
|
|
344
346
|
fileContent += "\n"
|
|
345
347
|
fileContent += " /**\n"
|
|
@@ -86,6 +86,25 @@ export default class VelociousCliCommandsTest extends BaseCommand {
|
|
|
86
86
|
process.exit(1)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
// Report the slowest tests so suite hotspots are visible every run. Defaults to
|
|
90
|
+
// the top 10; tune with VELOCIOUS_SLOW_TEST_COUNT (0 disables). Skipped for
|
|
91
|
+
// single-test runs where it would just be noise.
|
|
92
|
+
const slowTestCount = resolveSlowTestCount(process.env.VELOCIOUS_SLOW_TEST_COUNT)
|
|
93
|
+
|
|
94
|
+
if (slowTestCount > 0 && executedTests > 1) {
|
|
95
|
+
const slowestTests = testRunner.getSlowestTests(slowTestCount)
|
|
96
|
+
|
|
97
|
+
if (slowestTests.length > 0) {
|
|
98
|
+
console.log(picocolors.cyan(`\nSlowest ${slowestTests.length} tests:`))
|
|
99
|
+
|
|
100
|
+
for (const slowTest of slowestTests) {
|
|
101
|
+
const location = slowTest.filePath && slowTest.line ? ` (${slowTest.filePath}:${slowTest.line})` : ""
|
|
102
|
+
|
|
103
|
+
console.log(picocolors.cyan(` ${String(slowTest.durationMs).padStart(6)}ms ${slowTest.fullDescription}${location}`))
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
89
108
|
if (testRunner.isFailed()) {
|
|
90
109
|
await testRunner.persistFailedTestConsoleOutputsToAssets()
|
|
91
110
|
const failedTests = testRunner.getFailedTestDetails()
|
|
@@ -116,3 +135,16 @@ export default class VelociousCliCommandsTest extends BaseCommand {
|
|
|
116
135
|
}
|
|
117
136
|
}
|
|
118
137
|
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Resolves how many slowest tests to report from the `VELOCIOUS_SLOW_TEST_COUNT`
|
|
141
|
+
* env value: defaults to 10 when unset; 0 (or an unparseable value) disables the
|
|
142
|
+
* report; otherwise the floored, non-negative integer.
|
|
143
|
+
* @param {string | undefined} rawEnvValue - Raw env value.
|
|
144
|
+
* @returns {number} - Number of slowest tests to report (0 disables).
|
|
145
|
+
*/
|
|
146
|
+
export function resolveSlowTestCount(rawEnvValue) {
|
|
147
|
+
if (rawEnvValue === undefined) return 10
|
|
148
|
+
|
|
149
|
+
return Math.max(0, Math.floor(Number(rawEnvValue)) || 0)
|
|
150
|
+
}
|
|
@@ -299,6 +299,13 @@ export default class BackgroundJobsStore {
|
|
|
299
299
|
* @returns {Promise<void>} - Resolves when the schema is present.
|
|
300
300
|
*/
|
|
301
301
|
_applySchema(db: import("../database/drivers/base.js").default): Promise<void>;
|
|
302
|
+
/**
|
|
303
|
+
* Creates or upgrades the background-jobs tables, columns and concurrency rows on
|
|
304
|
+
* the given connection. Serialized per process by {@link BackgroundJobsStore#_applySchema}.
|
|
305
|
+
* @param {import("../database/drivers/base.js").default} db - Database connection.
|
|
306
|
+
* @returns {Promise<void>} - Resolves when the schema is present.
|
|
307
|
+
*/
|
|
308
|
+
_applySchemaSteps(db: import("../database/drivers/base.js").default): Promise<void>;
|
|
302
309
|
/**
|
|
303
310
|
* Runs ensure migrations table.
|
|
304
311
|
* @param {import("../database/drivers/base.js").default} db - Database connection.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/store.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/store.js"],"names":[],"mappings":"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"}
|