velocious 1.0.606 → 1.0.607
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 +44 -1
- package/build/background-jobs/job-semantics.js +145 -0
- package/build/background-jobs/local-adapter.js +161 -0
- package/build/background-jobs/local-dispatcher.js +418 -0
- package/build/background-jobs/local-job-registry.js +59 -0
- package/build/background-jobs/local-store.js +1219 -0
- package/build/background-jobs/store.js +33 -97
- package/build/background-jobs/types.js +26 -1
- package/build/configuration-types.js +3 -1
- package/build/configuration.js +16 -1
- package/build/database/drivers/sqlite/index.js +46 -41
- package/build/environment-handlers/browser.js +10 -0
- package/build/src/background-jobs/job-semantics.d.ts +65 -0
- package/build/src/background-jobs/job-semantics.d.ts.map +1 -0
- package/build/src/background-jobs/job-semantics.js +125 -0
- package/build/src/background-jobs/local-adapter.d.ts +161 -0
- package/build/src/background-jobs/local-adapter.d.ts.map +1 -0
- package/build/src/background-jobs/local-adapter.js +141 -0
- package/build/src/background-jobs/local-dispatcher.d.ts +185 -0
- package/build/src/background-jobs/local-dispatcher.d.ts.map +1 -0
- package/build/src/background-jobs/local-dispatcher.js +383 -0
- package/build/src/background-jobs/local-job-registry.d.ts +26 -0
- package/build/src/background-jobs/local-job-registry.d.ts.map +1 -0
- package/build/src/background-jobs/local-job-registry.js +51 -0
- package/build/src/background-jobs/local-store.d.ts +364 -0
- package/build/src/background-jobs/local-store.d.ts.map +1 -0
- package/build/src/background-jobs/local-store.js +1078 -0
- package/build/src/background-jobs/store.d.ts +0 -9
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +18 -88
- package/build/src/background-jobs/types.d.ts +97 -2
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +27 -2
- package/build/src/configuration-types.d.ts +9 -2
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +4 -2
- package/build/src/configuration.d.ts +5 -0
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +15 -2
- package/build/src/database/drivers/sqlite/index.d.ts +8 -0
- package/build/src/database/drivers/sqlite/index.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.js +47 -41
- package/build/src/environment-handlers/browser.d.ts +9 -0
- package/build/src/environment-handlers/browser.d.ts.map +1 -1
- package/build/src/environment-handlers/browser.js +10 -1
- package/build/src/testing/test-runner.d.ts +42 -10
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +135 -35
- package/build/testing/test-runner.js +141 -33
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/test-browser.js +5 -1
- package/src/background-jobs/job-semantics.js +145 -0
- package/src/background-jobs/local-adapter.js +161 -0
- package/src/background-jobs/local-dispatcher.js +418 -0
- package/src/background-jobs/local-job-registry.js +59 -0
- package/src/background-jobs/local-store.js +1219 -0
- package/src/background-jobs/store.js +33 -97
- package/src/background-jobs/types.js +26 -1
- package/src/configuration-types.js +3 -1
- package/src/configuration.js +16 -1
- package/src/database/drivers/sqlite/index.js +46 -41
- package/src/environment-handlers/browser.js +10 -0
- package/src/testing/test-runner.js +141 -33
|
@@ -111,6 +111,13 @@ import { SHARED_TRANSACTION_BROKER_ENV } from "./shared-transaction-proxy-driver
|
|
|
111
111
|
* ordinary test failure (the promise already settled).
|
|
112
112
|
* @typedef {Error & {velociousTestTimeout?: true}} TestTimeoutError
|
|
113
113
|
*/
|
|
114
|
+
/**
|
|
115
|
+
* SharedTransactionBrokerRegistration type.
|
|
116
|
+
* @typedef {object} SharedTransactionBrokerRegistration
|
|
117
|
+
* @property {SharedTransactionBroker} broker - Attempt broker and connection coordinator.
|
|
118
|
+
* @property {boolean} environmentPublished - Whether child-process coordinates were published.
|
|
119
|
+
* @property {string | undefined} previousEnvironment - Environment value to restore after publication.
|
|
120
|
+
*/
|
|
114
121
|
|
|
115
122
|
/**
|
|
116
123
|
* Runs run with timeout.
|
|
@@ -498,6 +505,7 @@ export default class TestRunner {
|
|
|
498
505
|
* @returns {boolean} - Whether the test should be skipped.
|
|
499
506
|
*/
|
|
500
507
|
shouldSkipTest(testArgs, testData, testDescription, descriptions, lineMatchedInScope) {
|
|
508
|
+
if (this.hasTag(testArgs, "browser-only") && !this.isBrowserTestMode()) return true
|
|
501
509
|
if (this.hasMatchingTag(testArgs.tags, this.getExcludeTagSet())) return true
|
|
502
510
|
|
|
503
511
|
if (this._includeTagSet.size > 0 && !testArgs.focus) {
|
|
@@ -634,12 +642,11 @@ export default class TestRunner {
|
|
|
634
642
|
}
|
|
635
643
|
|
|
636
644
|
/**
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
* @returns {Promise<{broker: SharedTransactionBroker, previousEnvironment: string | undefined} | undefined>} - Attempt registration.
|
|
645
|
+
* Selects the current non-tenant connections eligible for shared transaction work.
|
|
646
|
+
* @param {{transactionsOnly: boolean}} args - Selection options.
|
|
647
|
+
* @returns {Record<string, import("../database/drivers/base.js").default>} - Eligible connections by identifier.
|
|
641
648
|
*/
|
|
642
|
-
|
|
649
|
+
sharedTransactionConnections({transactionsOnly}) {
|
|
643
650
|
const configuration = this.getConfiguration()
|
|
644
651
|
const currentConnections = configuration.getCurrentConnections()
|
|
645
652
|
/** @type {Record<string, import("../database/drivers/base.js").default>} */
|
|
@@ -647,14 +654,78 @@ export default class TestRunner {
|
|
|
647
654
|
|
|
648
655
|
for (const [identifier, connection] of Object.entries(currentConnections)) {
|
|
649
656
|
const pool = configuration.getDatabasePool(identifier)
|
|
650
|
-
|
|
657
|
+
|
|
658
|
+
if (pool.getConfiguration().tenantOnly) continue
|
|
659
|
+
if (transactionsOnly && !connection.insideTransaction()) continue
|
|
651
660
|
connections[identifier] = connection
|
|
652
661
|
}
|
|
653
662
|
|
|
663
|
+
return connections
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Installs physical-connection coordination before a transaction-opening hook
|
|
668
|
+
* can expose the shared connection to a long-lived in-process service.
|
|
669
|
+
* Child-process coordinates remain unpublished until the transaction exists.
|
|
670
|
+
* @returns {Promise<SharedTransactionBrokerRegistration | undefined>} - Prepared coordinator.
|
|
671
|
+
*/
|
|
672
|
+
async prepareSharedTransactionBroker() {
|
|
673
|
+
const connections = this.sharedTransactionConnections({transactionsOnly: false})
|
|
674
|
+
|
|
675
|
+
if (Object.keys(connections).length === 0) return undefined
|
|
676
|
+
|
|
677
|
+
return {
|
|
678
|
+
broker: await SharedTransactionBroker.start({connections}),
|
|
679
|
+
environmentPublished: false,
|
|
680
|
+
previousEnvironment: undefined
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Checks whether a prepared broker coordinates exactly the selected physical connections.
|
|
686
|
+
* @param {SharedTransactionBrokerRegistration | undefined} registration - Prepared coordinator.
|
|
687
|
+
* @param {Record<string, import("../database/drivers/base.js").default>} connections - Selected connections.
|
|
688
|
+
* @returns {boolean} - Whether the identifier set and physical connections match exactly.
|
|
689
|
+
*/
|
|
690
|
+
sharedTransactionBrokerMatchesConnections(registration, connections) {
|
|
691
|
+
const identifiers = Object.keys(connections)
|
|
692
|
+
|
|
693
|
+
if (!registration || identifiers.length === 0) return false
|
|
694
|
+
if (Object.keys(registration.broker.connections).length !== identifiers.length) return false
|
|
695
|
+
|
|
696
|
+
for (const [identifier, connection] of Object.entries(connections)) {
|
|
697
|
+
if (registration.broker.connections[identifier] !== connection) return false
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
return true
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Starts a capability-scoped broker for the active non-tenant physical
|
|
705
|
+
* transaction connections. No broker/env is installed for truncation-only or
|
|
706
|
+
* other transaction-disabled attempts.
|
|
707
|
+
* @param {SharedTransactionBrokerRegistration} [preparedRegistration] - Coordinator prepared before hooks.
|
|
708
|
+
* @param {Record<string, import("../database/drivers/base.js").default>} [selectedConnections] - Post-hook active connections.
|
|
709
|
+
* @returns {Promise<SharedTransactionBrokerRegistration | undefined>} - Attempt registration.
|
|
710
|
+
*/
|
|
711
|
+
async startSharedTransactionBroker(preparedRegistration, selectedConnections) {
|
|
712
|
+
const connections = selectedConnections || this.sharedTransactionConnections({transactionsOnly: true})
|
|
713
|
+
|
|
654
714
|
const databaseIdentifiers = Object.keys(connections)
|
|
655
|
-
if (databaseIdentifiers.length === 0)
|
|
715
|
+
if (databaseIdentifiers.length === 0) {
|
|
716
|
+
await this.stopSharedTransactionBroker(preparedRegistration)
|
|
717
|
+
return undefined
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
let broker
|
|
721
|
+
|
|
722
|
+
if (preparedRegistration && this.sharedTransactionBrokerMatchesConnections(preparedRegistration, connections)) {
|
|
723
|
+
broker = preparedRegistration.broker
|
|
724
|
+
} else {
|
|
725
|
+
await this.stopSharedTransactionBroker(preparedRegistration)
|
|
726
|
+
broker = await SharedTransactionBroker.start({connections})
|
|
727
|
+
}
|
|
656
728
|
|
|
657
|
-
const broker = await SharedTransactionBroker.start({connections})
|
|
658
729
|
const previousEnvironment = process.env[SHARED_TRANSACTION_BROKER_ENV]
|
|
659
730
|
process.env[SHARED_TRANSACTION_BROKER_ENV] = Buffer.from(JSON.stringify({
|
|
660
731
|
address: broker.address(),
|
|
@@ -663,20 +734,23 @@ export default class TestRunner {
|
|
|
663
734
|
expected: true
|
|
664
735
|
})).toString("base64url")
|
|
665
736
|
|
|
666
|
-
return {broker, previousEnvironment}
|
|
737
|
+
return {broker, environmentPublished: true, previousEnvironment}
|
|
667
738
|
}
|
|
668
739
|
|
|
669
740
|
/**
|
|
670
741
|
* Revokes an attempt broker before database rollback hooks run and restores
|
|
671
742
|
* the caller's environment so later pooled/spawned children cannot inherit it.
|
|
672
|
-
* @param {
|
|
743
|
+
* @param {SharedTransactionBrokerRegistration | undefined} registration - Attempt registration.
|
|
673
744
|
*/
|
|
674
745
|
async stopSharedTransactionBroker(registration) {
|
|
675
746
|
if (!registration) return
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
747
|
+
|
|
748
|
+
if (registration.environmentPublished) {
|
|
749
|
+
if (registration.previousEnvironment === undefined) {
|
|
750
|
+
delete process.env[SHARED_TRANSACTION_BROKER_ENV]
|
|
751
|
+
} else {
|
|
752
|
+
process.env[SHARED_TRANSACTION_BROKER_ENV] = registration.previousEnvironment
|
|
753
|
+
}
|
|
680
754
|
}
|
|
681
755
|
await registration.broker.close()
|
|
682
756
|
}
|
|
@@ -1153,8 +1227,11 @@ export default class TestRunner {
|
|
|
1153
1227
|
let testLifecycle
|
|
1154
1228
|
/** @type {{pool: import("../database/pool/base.js").default, registration: import("../database/pool/base.js").TestSharedConnectionRegistration}[]} */
|
|
1155
1229
|
let testSharedConnectionRegistrations = []
|
|
1156
|
-
|
|
1230
|
+
let testSharedConnectionsActive = false
|
|
1231
|
+
/** @type {SharedTransactionBrokerRegistration | undefined} */
|
|
1157
1232
|
let sharedTransactionBrokerRegistration
|
|
1233
|
+
/** @type {SharedTransactionBrokerRegistration | undefined} */
|
|
1234
|
+
let sharedTransactionBrokerPreparation
|
|
1158
1235
|
const stopConsoleCapture = this.startConsoleCapture({
|
|
1159
1236
|
passthrough: testConfig.consoleOutput === "live"
|
|
1160
1237
|
})
|
|
@@ -1180,12 +1257,16 @@ export default class TestRunner {
|
|
|
1180
1257
|
await this.getConfiguration().ensureConnections({name: `Test: ${testDescription}`}, async () => {
|
|
1181
1258
|
// Register dynamic candidates before hooks so transaction state changes
|
|
1182
1259
|
// made during a hook are immediately visible to any in-process work.
|
|
1183
|
-
//
|
|
1184
|
-
//
|
|
1185
|
-
// as an HTTP request can dispatch work from inside the hook itself.
|
|
1260
|
+
// Prepare transaction sharing before hooks so long-lived services cannot
|
|
1261
|
+
// use the shared connection while its coordinator is still missing.
|
|
1186
1262
|
testSharedConnectionRegistrations = this.activateTestSharedConnections()
|
|
1263
|
+
testSharedConnectionsActive = true
|
|
1187
1264
|
|
|
1188
1265
|
try {
|
|
1266
|
+
if (testArgs.databaseCleaning?.transaction === true) {
|
|
1267
|
+
sharedTransactionBrokerPreparation = await this.prepareSharedTransactionBroker()
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1189
1270
|
try {
|
|
1190
1271
|
clearDeliveries()
|
|
1191
1272
|
for (const beforeEachData of newBeforeEaches) {
|
|
@@ -1199,9 +1280,18 @@ export default class TestRunner {
|
|
|
1199
1280
|
})
|
|
1200
1281
|
}
|
|
1201
1282
|
|
|
1202
|
-
|
|
1203
|
-
if (
|
|
1283
|
+
const activeSharedTransactionConnections = this.sharedTransactionConnections({transactionsOnly: true})
|
|
1284
|
+
if (sharedTransactionBrokerPreparation && !this.sharedTransactionBrokerMatchesConnections(sharedTransactionBrokerPreparation, activeSharedTransactionConnections)) {
|
|
1285
|
+
this.clearTestSharedConnections(testSharedConnectionRegistrations)
|
|
1286
|
+
testSharedConnectionRegistrations = []
|
|
1287
|
+
testSharedConnectionsActive = false
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
sharedTransactionBrokerRegistration = await this.startSharedTransactionBroker(sharedTransactionBrokerPreparation, activeSharedTransactionConnections)
|
|
1291
|
+
sharedTransactionBrokerPreparation = undefined
|
|
1292
|
+
if (sharedTransactionBrokerRegistration && !testSharedConnectionsActive) {
|
|
1204
1293
|
testSharedConnectionRegistrations = this.activateTestSharedConnections()
|
|
1294
|
+
testSharedConnectionsActive = true
|
|
1205
1295
|
}
|
|
1206
1296
|
|
|
1207
1297
|
// Record which test is running so an async crash (an unhandled
|
|
@@ -1217,22 +1307,35 @@ export default class TestRunner {
|
|
|
1217
1307
|
})
|
|
1218
1308
|
} finally {
|
|
1219
1309
|
try {
|
|
1220
|
-
|
|
1310
|
+
if (testSharedConnectionsActive) {
|
|
1311
|
+
this.clearTestSharedConnections(testSharedConnectionRegistrations)
|
|
1312
|
+
testSharedConnectionRegistrations = []
|
|
1313
|
+
testSharedConnectionsActive = false
|
|
1314
|
+
}
|
|
1221
1315
|
} finally {
|
|
1222
|
-
|
|
1223
|
-
await this.
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1316
|
+
try {
|
|
1317
|
+
await this.stopSharedTransactionBroker(sharedTransactionBrokerRegistration || sharedTransactionBrokerPreparation)
|
|
1318
|
+
sharedTransactionBrokerRegistration = undefined
|
|
1319
|
+
sharedTransactionBrokerPreparation = undefined
|
|
1320
|
+
} finally {
|
|
1321
|
+
for (const afterEachData of newAfterEaches) {
|
|
1322
|
+
await this.runProfileSpan({
|
|
1323
|
+
phase: "afterEach",
|
|
1324
|
+
declarationIndex: afterEachData.declarationIndex,
|
|
1325
|
+
declarationScopeId: afterEachData.declarationScopeId,
|
|
1326
|
+
filePath: afterEachData.ownerFilePath
|
|
1327
|
+
}, async () => {
|
|
1328
|
+
await afterEachData.callback({configuration: this.getConfiguration(), testArgs, testData})
|
|
1329
|
+
})
|
|
1330
|
+
}
|
|
1231
1331
|
}
|
|
1232
1332
|
}
|
|
1233
1333
|
}
|
|
1234
1334
|
} finally {
|
|
1235
|
-
|
|
1335
|
+
if (testSharedConnectionsActive) {
|
|
1336
|
+
this.clearTestSharedConnections(testSharedConnectionRegistrations)
|
|
1337
|
+
testSharedConnectionsActive = false
|
|
1338
|
+
}
|
|
1236
1339
|
}
|
|
1237
1340
|
})
|
|
1238
1341
|
})
|
|
@@ -1283,9 +1386,14 @@ export default class TestRunner {
|
|
|
1283
1386
|
// ensureConnections before activateTestSharedConnections() replaces
|
|
1284
1387
|
// it. Clear it here so the next test checks out a fresh connection.
|
|
1285
1388
|
// Idempotent when the lifecycle did settle and already cleared.
|
|
1286
|
-
|
|
1389
|
+
if (testSharedConnectionsActive) {
|
|
1390
|
+
this.clearTestSharedConnections(testSharedConnectionRegistrations)
|
|
1391
|
+
testSharedConnectionRegistrations = []
|
|
1392
|
+
testSharedConnectionsActive = false
|
|
1393
|
+
}
|
|
1394
|
+
await this.stopSharedTransactionBroker(sharedTransactionBrokerRegistration || sharedTransactionBrokerPreparation)
|
|
1287
1395
|
sharedTransactionBrokerRegistration = undefined
|
|
1288
|
-
|
|
1396
|
+
sharedTransactionBrokerPreparation = undefined
|
|
1289
1397
|
}
|
|
1290
1398
|
|
|
1291
1399
|
willRetry = retriesUsed < retryCount
|