@aventara/core 1.0.0-rc.0 → 1.0.0-rc.2
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/CHANGELOG.md +1434 -0
- package/ERRORS.md +142 -0
- package/README.md +247 -57
- package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
- package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
- package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
- package/dist/adapters/adapter-field.d.ts +25 -11
- package/dist/adapters/adapter-identifier.d.ts +6 -6
- package/dist/adapters/adapter-model.d.ts +18 -9
- package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
- package/dist/adapters/adapter-operation.d.ts +3 -3
- package/dist/adapters/adapter-resource.d.ts +18 -9
- package/dist/adapters/adapter-sql-statement.d.ts +19 -0
- package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
- package/dist/adapters/adapter.interface.d.ts +59 -29
- package/dist/avz/avz-check.factory.d.ts +83 -0
- package/dist/avz/avz-check.factory.js +116 -0
- package/dist/avz/avz-check.registry.d.ts +35 -0
- package/dist/avz/avz-check.registry.js +9 -0
- package/dist/avz/avz.d.ts +203 -0
- package/dist/{json → avz}/avz.js +150 -8
- package/dist/{json → avz}/index.d.ts +2 -1
- package/dist/{json → avz}/json-shape.registry.d.ts +7 -7
- package/dist/{json → avz}/zod-issue.translator.d.ts +8 -2
- package/dist/{json → avz}/zod-issue.translator.js +7 -0
- package/dist/compiler/contract-compiler-diagnostic.d.ts +31 -5
- package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
- package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
- package/dist/compiler/contract.compiler.d.ts +18 -18
- package/dist/compiler/contract.compiler.js +637 -442
- package/dist/compiler/create-requirements.projector.d.ts +49 -0
- package/dist/compiler/create-requirements.projector.js +423 -0
- package/dist/compiler/field-validator.compiler.d.ts +47 -0
- package/dist/compiler/field-validator.compiler.js +238 -0
- package/dist/config/any-framework-config.d.ts +19 -12
- package/dist/config/computed-fields.d.ts +62 -0
- package/dist/config/computed-fields.js +80 -0
- package/dist/config/config-diagnostic.d.ts +11 -4
- package/dist/config/config-diagnostic.guidance.d.ts +6 -0
- package/dist/config/config-diagnostic.guidance.js +32 -0
- package/dist/config/config-layer.d.ts +15 -6
- package/dist/config/config.resolver.d.ts +74 -31
- package/dist/config/config.resolver.js +108 -44
- package/dist/config/config.validator.d.ts +7 -7
- package/dist/config/config.validator.js +581 -72
- package/dist/config/define-resource.d.ts +57 -0
- package/dist/config/define-resource.js +14 -0
- package/dist/config/effective-fields.d.ts +19 -23
- package/dist/config/entrypoint.normalizer.d.ts +1 -1
- package/dist/config/exact-framework-config.d.ts +308 -0
- package/dist/config/field-compute.resolver.d.ts +21 -0
- package/dist/config/field-compute.resolver.js +123 -0
- package/dist/config/field-pipeline-config.d.ts +47 -0
- package/dist/config/forced-operation.validator.d.ts +10 -0
- package/dist/config/forced-operation.validator.js +66 -0
- package/dist/config/framework-config.d.ts +111 -39
- package/dist/config/framework-exemptions-config.d.ts +91 -0
- package/dist/config/framework-exemptions-config.js +1 -0
- package/dist/config/framework-field-definition.d.ts +78 -0
- package/dist/config/framework-field-definition.js +28 -0
- package/dist/config/framework-resources-config.d.ts +122 -0
- package/dist/config/framework-resources-config.js +1 -0
- package/dist/config/pipeline-config.d.ts +56 -20
- package/dist/config/pipeline-tree.resolver.d.ts +79 -0
- package/dist/config/pipeline-tree.resolver.js +220 -0
- package/dist/config/stage-type.eraser.d.ts +65 -0
- package/dist/config/stage-type.eraser.js +1 -0
- package/dist/contracts/capability.d.ts +21 -12
- package/dist/contracts/capability.js +2 -0
- package/dist/contracts/client-contract-structure.validator.d.ts +388 -63
- package/dist/contracts/client-contract-structure.validator.js +156 -10
- package/dist/contracts/contract-canonicalizer.d.ts +26 -3
- package/dist/contracts/contract-canonicalizer.js +156 -29
- package/dist/contracts/contract-hash.d.ts +12 -7
- package/dist/contracts/contract-hash.js +3 -2
- package/dist/contracts/contract-limits.d.ts +4 -1
- package/dist/contracts/contract-limits.js +1 -0
- package/dist/contracts/contract-lookup.d.ts +5 -5
- package/dist/contracts/contract-protocol.d.ts +4 -4
- package/dist/contracts/contract.d.ts +24 -16
- package/dist/contracts/create-requirements.d.ts +35 -0
- package/dist/contracts/create-requirements.js +1 -0
- package/dist/contracts/enum-definition.d.ts +1 -1
- package/dist/contracts/field-check.d.ts +101 -0
- package/dist/contracts/field-check.js +1 -0
- package/dist/contracts/field.d.ts +81 -42
- package/dist/contracts/identifier.d.ts +4 -4
- package/dist/contracts/json-shape.d.ts +12 -1
- package/dist/contracts/lifecycle-trait.d.ts +2 -2
- package/dist/contracts/resource-operations.d.ts +28 -28
- package/dist/contracts/resource.d.ts +15 -9
- package/dist/contracts/scalar-value-type.d.ts +15 -15
- package/dist/contracts/scalar.d.ts +3 -3
- package/dist/contracts/transaction-capability.d.ts +1 -1
- package/dist/contracts/wire-scalar-format.d.ts +4 -4
- package/dist/framework/contract-view.d.ts +213 -147
- package/dist/framework/framework-construction.error.d.ts +19 -10
- package/dist/framework/framework-construction.error.js +7 -3
- package/dist/framework/framework.d.ts +47 -23
- package/dist/framework/framework.factory.d.ts +8 -6
- package/dist/framework/framework.factory.js +49 -22
- package/dist/framework/operation-facade.d.ts +123 -52
- package/dist/framework/operation-facade.js +9 -1
- package/dist/index.d.ts +57 -50
- package/dist/index.js +7 -6
- package/dist/internal.d.ts +17 -10
- package/dist/internal.js +4 -1
- package/dist/operations/database-refusal.d.ts +51 -0
- package/dist/operations/database-refusal.js +45 -0
- package/dist/operations/operation-arguments.d.ts +343 -207
- package/dist/operations/operation-call.d.ts +27 -28
- package/dist/operations/operation-identity.d.ts +10 -10
- package/dist/operations/operation-result.d.ts +21 -21
- package/dist/operations/operation-validator-core.d.ts +6 -6
- package/dist/operations/operation-validator-core.js +99 -6
- package/dist/operations/operation-validator.d.ts +9 -9
- package/dist/operations/projection-scope.resolver.d.ts +6 -6
- package/dist/operations/structural-limits.walker.d.ts +6 -6
- package/dist/operations/structural-limits.walker.js +145 -0
- package/dist/operations/validation-code.d.ts +11 -6
- package/dist/operations/validation-code.guidance.d.ts +6 -0
- package/dist/operations/validation-code.guidance.js +90 -0
- package/dist/operations/validation-code.js +4 -0
- package/dist/operations/write-scope.resolver.d.ts +10 -6
- package/dist/operations/write-scope.resolver.js +2 -0
- package/dist/protocol/absent-route.responder.d.ts +13 -12
- package/dist/protocol/absent-route.responder.js +19 -19
- package/dist/protocol/contract-document.responder.d.ts +3 -3
- package/dist/protocol/contract-document.responder.js +2 -2
- package/dist/protocol/http-request.decoder.d.ts +17 -13
- package/dist/protocol/http-request.decoder.js +10 -10
- package/dist/protocol/http-request.reader.d.ts +3 -3
- package/dist/protocol/http-response.encoder.d.ts +4 -4
- package/dist/protocol/http-response.encoder.js +94 -55
- package/dist/protocol/http-status.table.d.ts +2 -2
- package/dist/protocol/operation-response.guard.d.ts +2 -2
- package/dist/protocol/protocol-surface.d.ts +4 -4
- package/dist/protocol/protocol.binder.d.ts +50 -27
- package/dist/protocol/protocol.binder.js +12 -9
- package/dist/protocol/protocol.handler.d.ts +22 -13
- package/dist/protocol/protocol.handler.js +91 -17
- package/dist/protocol/unmounted-route.error.d.ts +4 -4
- package/dist/protocol/unmounted-route.error.js +2 -2
- package/dist/runtime/caller-data.copier.d.ts +22 -5
- package/dist/runtime/caller-data.copier.js +31 -14
- package/dist/runtime/caller-data.door.d.ts +17 -11
- package/dist/runtime/caller-data.door.js +6 -4
- package/dist/runtime/computed-read-runtime.d.ts +7 -6
- package/dist/runtime/computed-read-runtime.js +76 -50
- package/dist/runtime/computed-value.error.d.ts +7 -6
- package/dist/runtime/computed-value.error.js +5 -4
- package/dist/runtime/context-executor.runtime.d.ts +59 -0
- package/dist/runtime/context-executor.runtime.js +275 -0
- package/dist/runtime/create-requirement.d.ts +44 -79
- package/dist/runtime/create-requirement.js +213 -73
- package/dist/runtime/decimal.d.ts +2 -2
- package/dist/runtime/decimal.js +1 -1
- package/dist/runtime/diagnostics-reporter.d.ts +54 -27
- package/dist/runtime/diagnostics-reporter.js +24 -0
- package/dist/runtime/error-boundary.d.ts +65 -8
- package/dist/runtime/error-boundary.js +49 -19
- package/dist/runtime/error-guidance.d.ts +12 -0
- package/dist/runtime/error-guidance.js +1 -0
- package/dist/runtime/error.catalog.d.ts +49 -0
- package/dist/runtime/error.catalog.js +49 -0
- package/dist/runtime/execution-options.d.ts +10 -2
- package/dist/runtime/field-check.evaluator.d.ts +29 -0
- package/dist/runtime/field-check.evaluator.js +521 -0
- package/dist/runtime/field-compute.d.ts +64 -0
- package/dist/runtime/field-compute.js +1 -0
- package/dist/runtime/field-stage.plan.d.ts +15 -0
- package/dist/runtime/field-stage.plan.js +27 -0
- package/dist/runtime/field-stage.runtime.d.ts +37 -0
- package/dist/runtime/field-stage.runtime.js +147 -0
- package/dist/runtime/field-validator.runtime.d.ts +19 -0
- package/dist/runtime/field-validator.runtime.js +92 -0
- package/dist/runtime/framework-error-class.table.d.ts +33 -0
- package/dist/runtime/framework-error-class.table.js +25 -0
- package/dist/runtime/framework-error.d.ts +68 -8
- package/dist/runtime/framework-error.factory.d.ts +4 -0
- package/dist/runtime/framework-error.factory.js +15 -0
- package/dist/runtime/framework-error.js +23 -2
- package/dist/runtime/interceptor-next.error.d.ts +5 -0
- package/dist/runtime/interceptor-next.error.js +6 -0
- package/dist/runtime/json-value.d.ts +11 -6
- package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
- package/dist/runtime/level-lifecycle.runtime.js +39 -0
- package/dist/runtime/misuse-reporter.d.ts +12 -12
- package/dist/runtime/mutation-planner.d.ts +19 -10
- package/dist/runtime/mutation-planner.js +48 -35
- package/dist/runtime/nested-write.walker.d.ts +32 -0
- package/dist/runtime/nested-write.walker.js +73 -0
- package/dist/runtime/operation-code.guidance.d.ts +6 -0
- package/dist/runtime/operation-code.guidance.js +167 -0
- package/dist/runtime/operation-request.d.ts +33 -6
- package/dist/runtime/operation-response.d.ts +17 -17
- package/dist/runtime/operation-runtime.d.ts +127 -25
- package/dist/runtime/operation-runtime.js +441 -78
- package/dist/runtime/outcome-mapper.d.ts +16 -5
- package/dist/runtime/outcome-mapper.js +23 -6
- package/dist/runtime/output-validator.d.ts +10 -10
- package/dist/runtime/output-validator.js +3 -3
- package/dist/runtime/owned-execution.registry.d.ts +16 -6
- package/dist/runtime/pipe-output.validator.d.ts +43 -18
- package/dist/runtime/pipe-output.validator.js +15 -13
- package/dist/runtime/pipeline.d.ts +223 -34
- package/dist/runtime/readonly-value.d.ts +43 -0
- package/dist/runtime/readonly-value.js +150 -0
- package/dist/runtime/request-envelope.validator.d.ts +3 -3
- package/dist/runtime/request-envelope.validator.js +12 -7
- package/dist/runtime/request-id.d.ts +1 -1
- package/dist/runtime/request-state.d.ts +14 -0
- package/dist/runtime/request-state.js +1 -0
- package/dist/runtime/request-state.resolver.d.ts +12 -0
- package/dist/runtime/request-state.resolver.js +20 -0
- package/dist/runtime/scalar-runtime.d.ts +35 -16
- package/dist/runtime/scalar-runtime.js +102 -34
- package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
- package/dist/runtime/unsent-value.normalizer.js +128 -0
- package/dist/transactions/deferred-operation.d.ts +35 -20
- package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
- package/dist/transactions/operation-arguments-encoder.js +2 -2
- package/dist/transactions/operation-fingerprint.js +2 -2
- package/dist/transactions/sql-statement.d.ts +85 -0
- package/dist/transactions/sql-statement.js +47 -0
- package/dist/transactions/sql-statement.validator.d.ts +44 -0
- package/dist/transactions/sql-statement.validator.js +167 -0
- package/dist/transactions/transaction-envelope.d.ts +4 -4
- package/dist/transactions/transaction-integrity-error.d.ts +6 -6
- package/dist/transactions/transaction-integrity-error.js +5 -2
- package/dist/transactions/transaction-plan-assembler.d.ts +21 -11
- package/dist/transactions/transaction-plan-assembler.js +169 -32
- package/dist/transactions/transaction-plan-validator.d.ts +45 -20
- package/dist/transactions/transaction-plan-validator.js +96 -38
- package/dist/transactions/transaction-reference-collector.d.ts +5 -5
- package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
- package/dist/transactions/transaction-reference-resolver.js +26 -14
- package/dist/transactions/transaction-reference-validator.d.ts +76 -4
- package/dist/transactions/transaction-reference-validator.js +129 -71
- package/dist/transactions/transaction-reference.d.ts +13 -13
- package/dist/transactions/transaction-reference.js +5 -0
- package/dist/transactions/transaction-request.d.ts +18 -5
- package/dist/transactions/transaction-response.d.ts +6 -6
- package/dist/transactions/transaction-runtime.d.ts +8 -7
- package/dist/transactions/transaction-runtime.js +191 -50
- package/dist/transactions/transaction-settlement.runtime.d.ts +51 -0
- package/dist/transactions/transaction-settlement.runtime.js +120 -0
- package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
- package/dist/transactions/transaction-slot-path-error.js +2 -2
- package/dist/transactions/transaction-slot-writer.js +2 -2
- package/dist/transactions/transaction-stage.runtime.d.ts +82 -0
- package/dist/transactions/transaction-stage.runtime.js +126 -0
- package/package.json +9 -7
- package/src/runtime/field-check.evaluator.ts +720 -0
- package/dist/config/define-fields.d.ts +0 -42
- package/dist/config/define-fields.js +0 -3
- package/dist/config/framework-behaviors-config.d.ts +0 -30
- package/dist/config/framework-fields-config.d.ts +0 -42
- package/dist/config/framework-restrictions-config.d.ts +0 -142
- package/dist/json/avz.d.ts +0 -96
- package/dist/runtime/field-behavior.d.ts +0 -48
- /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
- /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
- /package/dist/{json → avz}/index.js +0 -0
- /package/dist/{json → avz}/json-shape.registry.js +0 -0
- /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
- /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
|
@@ -1,81 +1,222 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { planOperationArgumentsPath } from "../runtime/error-boundary.js";
|
|
3
|
-
import { internalFailure } from "../runtime/operation-response.js";
|
|
4
|
-
import {
|
|
1
|
+
import { transactionLevelsOf } from "../config/pipeline-tree.resolver.js";
|
|
2
|
+
import { AdapterBoundary, planOperationArgumentsPath, planStepPath, sanitizeOperationFailure, } from "../runtime/error-boundary.js";
|
|
3
|
+
import { internalFailure, operationSuccess, } from "../runtime/operation-response.js";
|
|
4
|
+
import { admitOperation, EVERY_FIELD, executeAdmittedOperation, prepareStep, STEP_PIPES, withRequestState, } from "../runtime/operation-runtime.js";
|
|
5
5
|
import { mapValidationOutcome } from "../runtime/outcome-mapper.js";
|
|
6
|
+
import { refusedStageOutput, serverContractFor, } from "../runtime/pipe-output.validator.js";
|
|
6
7
|
import { resolveCascadeClosure } from "../runtime/referential-action.js";
|
|
7
|
-
import {
|
|
8
|
+
import { AvTransactionIntegrityError } from "./transaction-integrity-error.js";
|
|
8
9
|
import { validateTransactionPlan } from "./transaction-plan-validator.js";
|
|
9
|
-
import {
|
|
10
|
+
import { collectTransactionReferenceCandidates } from "./transaction-reference-collector.js";
|
|
11
|
+
import { resolveSqlStatement, resolveTransactionReferences, } from "./transaction-reference-resolver.js";
|
|
12
|
+
import { validateReferenceSlots } from "./transaction-reference-validator.js";
|
|
10
13
|
import { transactionCommitted, transactionInfrastructureFailure, transactionOperationFailure, } from "./transaction-response.js";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
...runtimeDependencies,
|
|
16
|
-
recordWrites: recordWriteFactsOf(adapter),
|
|
17
|
-
};
|
|
14
|
+
import { settleTransaction } from "./transaction-settlement.runtime.js";
|
|
15
|
+
import { TRANSACTION_PIPES, touchedTransactionLevels, transactionFacts, } from "./transaction-stage.runtime.js";
|
|
16
|
+
export function createTransactionRuntime(dependencies, pipelineDependencies) {
|
|
17
|
+
const { adapter } = dependencies;
|
|
18
18
|
const planDependencies = {
|
|
19
19
|
...pipelineDependencies,
|
|
20
20
|
cascades: resolveCascadeClosure(adapter.referentialActions),
|
|
21
|
+
sqlStatements: adapter.sqlStatements === true,
|
|
21
22
|
};
|
|
22
|
-
return async (
|
|
23
|
+
return async (seeded, diagnostics, origins, planArguments) => {
|
|
24
|
+
const request = withRequestState(seeded);
|
|
23
25
|
const validation = await validateTransactionPlan(planDependencies, request, origins, planArguments);
|
|
24
26
|
if (!validation.ok) {
|
|
25
27
|
return validation.response;
|
|
26
28
|
}
|
|
27
|
-
return executeTransactionPlan(adapter, pipelineDependencies, validation.plan, diagnostics);
|
|
29
|
+
return executeTransactionPlan(adapter, pipelineDependencies, request, validation.plan, request.state, diagnostics);
|
|
28
30
|
};
|
|
29
31
|
}
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
function planOrigin(request, plan) {
|
|
33
|
+
for (const step of plan.operations) {
|
|
34
|
+
if (step.kind === "operation") {
|
|
35
|
+
return step.request;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return request;
|
|
39
|
+
}
|
|
40
|
+
function stepView(step, args) {
|
|
41
|
+
if (step.kind === "sql") {
|
|
42
|
+
return {
|
|
43
|
+
sql: {
|
|
44
|
+
strings: step.strings,
|
|
45
|
+
values: step.values.map((value) => value.kind === "value"
|
|
46
|
+
? value.value
|
|
47
|
+
: { $ref: { operation: value.operation, path: [value.field] } }),
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
resource: step.request.resource,
|
|
53
|
+
family: step.request.family,
|
|
54
|
+
variant: step.request.variant,
|
|
55
|
+
args,
|
|
36
56
|
};
|
|
37
|
-
|
|
38
|
-
|
|
57
|
+
}
|
|
58
|
+
function pathKey(path) {
|
|
59
|
+
return JSON.stringify(path);
|
|
60
|
+
}
|
|
61
|
+
function relativeSlotPath(operation, path) {
|
|
62
|
+
return path.slice(planOperationArgumentsPath(operation.index).length);
|
|
63
|
+
}
|
|
64
|
+
function standingReferences(core, operation, args, steps, subject) {
|
|
65
|
+
const candidates = collectTransactionReferenceCandidates(serverContractFor(core, operation.contract), operation.request, operation.index, args);
|
|
66
|
+
const validation = validateReferenceSlots(candidates, steps, operation.index);
|
|
67
|
+
if (validation.ok) {
|
|
68
|
+
return validation;
|
|
39
69
|
}
|
|
40
|
-
const
|
|
70
|
+
const { issue } = validation;
|
|
71
|
+
const refused = refusedStageOutput(operation.request, [
|
|
72
|
+
{
|
|
73
|
+
...issue,
|
|
74
|
+
path: ["arguments", ...relativeSlotPath(operation, issue.path ?? [])],
|
|
75
|
+
},
|
|
76
|
+
], subject);
|
|
77
|
+
if (refused === undefined) {
|
|
78
|
+
throw new TypeError("A refused reference produced no refusal.");
|
|
79
|
+
}
|
|
80
|
+
return { ok: false, ...refused };
|
|
81
|
+
}
|
|
82
|
+
async function executeTransactionPlan(adapter, dependencies, request, plan, state, diagnostics) {
|
|
83
|
+
const stateful = (operation) => ({ ...operation.request, state });
|
|
84
|
+
const admitted = [];
|
|
85
|
+
const standing = [];
|
|
86
|
+
for (const step of plan.operations) {
|
|
87
|
+
if (step.kind === "sql") {
|
|
88
|
+
admitted.push({ ok: true, args: undefined, piped: false });
|
|
89
|
+
standing.push([]);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const report = diagnostics.operation(step.request, step.index);
|
|
93
|
+
const admission = await admitOperation(dependencies, stateful(step), step.contract, step.arguments, planOperationArgumentsPath(step.index), report, { requestId: request.requestId, transaction: undefined, state }, {
|
|
94
|
+
select: EVERY_FIELD,
|
|
95
|
+
validation: { transactionReferences: true },
|
|
96
|
+
beforeBegin: true,
|
|
97
|
+
});
|
|
98
|
+
if (!admission.ok) {
|
|
99
|
+
return transactionOperationFailure(admission.response, step.index);
|
|
100
|
+
}
|
|
101
|
+
if (!admission.piped) {
|
|
102
|
+
standing.push(step.references);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const references = standingReferences(dependencies.contracts.core, step, admission.args, plan.operations, STEP_PIPES);
|
|
106
|
+
if (!references.ok) {
|
|
107
|
+
report(references.error, "A3004");
|
|
108
|
+
return transactionOperationFailure(references.response, step.index);
|
|
109
|
+
}
|
|
110
|
+
standing.push(references.references);
|
|
111
|
+
}
|
|
112
|
+
admitted.push(admission);
|
|
113
|
+
}
|
|
114
|
+
const origin = planOrigin(request, plan);
|
|
115
|
+
const contract = dependencies.contracts[origin.origin];
|
|
116
|
+
const tree = dependencies.config[origin.origin].pipelines;
|
|
117
|
+
const view = plan.operations.map((step, index) => stepView(step, admitted[index]?.args));
|
|
118
|
+
const runPlanOperation = async (operation, args, transactionPiped, executor, results, outer) => {
|
|
41
119
|
const report = diagnostics.operation(operation.request, operation.index);
|
|
120
|
+
const argumentsPath = planOperationArgumentsPath(operation.index);
|
|
121
|
+
const stepRequest = stateful(operation);
|
|
42
122
|
try {
|
|
43
|
-
|
|
123
|
+
let live = standing[operation.index] ?? operation.references;
|
|
124
|
+
if (transactionPiped) {
|
|
125
|
+
const references = standingReferences(dependencies.contracts.core, operation, args, plan.operations, TRANSACTION_PIPES);
|
|
126
|
+
if (!references.ok) {
|
|
127
|
+
report(references.error, "A3004");
|
|
128
|
+
return references.response;
|
|
129
|
+
}
|
|
130
|
+
live = references.references;
|
|
131
|
+
}
|
|
132
|
+
const resolved = resolveTransactionReferences({
|
|
133
|
+
...operation,
|
|
134
|
+
arguments: args,
|
|
135
|
+
references: live,
|
|
136
|
+
}, results);
|
|
44
137
|
if (!resolved.ok) {
|
|
45
138
|
return mapValidationOutcome(resolved.issues);
|
|
46
139
|
}
|
|
47
|
-
|
|
140
|
+
const written = new Set(live
|
|
141
|
+
.filter((slot) => slot.written)
|
|
142
|
+
.map((slot) => pathKey(relativeSlotPath(operation, slot.path))));
|
|
143
|
+
const prepared = await prepareStep(dependencies, stepRequest, operation.contract, resolved.arguments, argumentsPath, report, executor, {
|
|
144
|
+
written: (path) => written.has(pathKey(path)),
|
|
145
|
+
transactionPiped,
|
|
146
|
+
pipedAroundReferences: admitted[operation.index]?.piped === true &&
|
|
147
|
+
(live.length > 0 || operation.references.length > 0),
|
|
148
|
+
}, outer);
|
|
149
|
+
if (!prepared.ok) {
|
|
150
|
+
return prepared.response;
|
|
151
|
+
}
|
|
152
|
+
return await executeAdmittedOperation(dependencies, stepRequest, operation.contract, prepared.args, argumentsPath, { kind: "transaction", executor, outer }, report);
|
|
48
153
|
}
|
|
49
154
|
catch (error) {
|
|
50
155
|
report(error, "A3000");
|
|
51
156
|
return internalFailure();
|
|
52
157
|
}
|
|
53
158
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
159
|
+
const runSqlStatement = async (step, executor, results) => {
|
|
160
|
+
const report = diagnostics.transaction(step.index);
|
|
161
|
+
const boundary = new AdapterBoundary();
|
|
162
|
+
try {
|
|
163
|
+
const resolved = resolveSqlStatement(step, results);
|
|
164
|
+
if (!resolved.ok) {
|
|
165
|
+
return mapValidationOutcome(resolved.issues);
|
|
166
|
+
}
|
|
167
|
+
if (typeof executor.executeSql !== "function") {
|
|
168
|
+
report(new AvTransactionIntegrityError("statement-unavailable"), "A3002");
|
|
169
|
+
return transactionInfrastructureFailure();
|
|
170
|
+
}
|
|
171
|
+
const executeSql = executor.executeSql.bind(executor);
|
|
172
|
+
try {
|
|
173
|
+
const rows = await boundary.execute(async () => {
|
|
174
|
+
const answer = await executeSql(resolved.statement);
|
|
175
|
+
if (!Array.isArray(answer)) {
|
|
176
|
+
throw new TypeError("Adapter executeSql must resolve the statement's rows as an array.");
|
|
177
|
+
}
|
|
178
|
+
return answer;
|
|
179
|
+
});
|
|
180
|
+
return operationSuccess([...rows], "A1000");
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
return sanitizeOperationFailure(error, boundary.originOf(error), report, {
|
|
184
|
+
path: [...planStepPath(step.index), "values"],
|
|
185
|
+
arguments: resolved.statement.values,
|
|
186
|
+
});
|
|
63
187
|
}
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
if (error !== TRANSACTION_ABORT) {
|
|
68
|
-
return infrastructureFailure(error);
|
|
69
188
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
189
|
+
catch (error) {
|
|
190
|
+
report(error, "A3000");
|
|
191
|
+
return internalFailure();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const settled = await settleTransaction({
|
|
195
|
+
adapter,
|
|
196
|
+
levels: touchedTransactionLevels(view, (resource) => transactionLevelsOf(tree, resource)),
|
|
197
|
+
plan: view,
|
|
198
|
+
contextOf: (current, executor) => dependencies.contexts.transaction({ requestId: origin.requestId, transaction: executor, state }, transactionFacts(contract, origin, current)),
|
|
199
|
+
failureView: { path: ["operations"], arguments: view },
|
|
200
|
+
report: diagnostics.transaction(),
|
|
201
|
+
runStep: (index, step, piped, executor, results, outer) => {
|
|
202
|
+
const operation = plan.operations[index];
|
|
203
|
+
if (operation === undefined) {
|
|
204
|
+
throw new TypeError(`Transaction step ${index} is not in the plan.`);
|
|
205
|
+
}
|
|
206
|
+
return operation.kind === "sql"
|
|
207
|
+
? runSqlStatement(operation, executor, results)
|
|
208
|
+
: runPlanOperation(operation, step.args, piped, executor, results, outer);
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
switch (settled.kind) {
|
|
212
|
+
case "committed":
|
|
213
|
+
return transactionCommitted(settled.responses.map((response) => response.data));
|
|
214
|
+
case "rolled-back":
|
|
215
|
+
return settled.operation === undefined
|
|
216
|
+
? settled.response
|
|
217
|
+
: transactionOperationFailure(settled.response, settled.operation);
|
|
218
|
+
case "broken":
|
|
219
|
+
diagnostics.transaction(settled.operation)(settled.error, "A3002");
|
|
220
|
+
return transactionInfrastructureFailure(settled.operation);
|
|
79
221
|
}
|
|
80
|
-
return transactionCommitted([...ledger.results]);
|
|
81
222
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { AvAdapter } from "../adapters/adapter.interface.js";
|
|
2
|
+
import type { AvAdapterModel } from "../adapters/adapter-model.js";
|
|
3
|
+
import type { AvAdapterTransactionExecutor } from "../adapters/adapter-transaction-executor.interface.js";
|
|
4
|
+
import type { ResolvedTransactionPipelineConfig } from "../config/pipeline-config.js";
|
|
5
|
+
import type { DiagnosticsReporter } from "../runtime/diagnostics-reporter.js";
|
|
6
|
+
import { type CallerArgumentsView, type OuterFailureLayer } from "../runtime/error-boundary.js";
|
|
7
|
+
import type { AvOperationFailureResponse, AvOperationResponse } from "../runtime/operation-response.js";
|
|
8
|
+
import type { AvTransactionContext } from "../runtime/pipeline.js";
|
|
9
|
+
import { type TransactionStepView } from "./transaction-stage.runtime.js";
|
|
10
|
+
/**
|
|
11
|
+
* Runs one step inside the open transaction: `step` as the transaction pipes
|
|
12
|
+
* left it, `piped` whether one ran, `results` the completed steps' data in plan
|
|
13
|
+
* order, `outer` where an error the step's own filters leave unhandled is handed:
|
|
14
|
+
* the touched Resources' transaction filters answer it once the transaction
|
|
15
|
+
* interceptors have unwound. Its answer is the step's own outcome.
|
|
16
|
+
*/
|
|
17
|
+
export type TransactionStepRunner<M extends AvAdapterModel> = (index: number, step: TransactionStepView, piped: boolean, executor: AvAdapterTransactionExecutor<M>, results: readonly unknown[], outer: OuterFailureLayer) => Promise<AvOperationResponse>;
|
|
18
|
+
/** How one transaction settled. */
|
|
19
|
+
export type TransactionSettlement =
|
|
20
|
+
/** Committed: every step's own outcome, in plan order. */
|
|
21
|
+
{
|
|
22
|
+
readonly kind: "committed";
|
|
23
|
+
readonly responses: readonly AvOperationResponse[];
|
|
24
|
+
}
|
|
25
|
+
/** Rolled back on a deliberate outcome: a step's (with its index) or a stage's. */
|
|
26
|
+
| {
|
|
27
|
+
readonly kind: "rolled-back";
|
|
28
|
+
readonly response: AvOperationFailureResponse;
|
|
29
|
+
readonly operation: number | undefined;
|
|
30
|
+
}
|
|
31
|
+
/** The transaction contract broke: `A3002`, the error for diagnostics. */
|
|
32
|
+
| {
|
|
33
|
+
readonly kind: "broken";
|
|
34
|
+
readonly error: unknown;
|
|
35
|
+
readonly operation: number | undefined;
|
|
36
|
+
};
|
|
37
|
+
export type TransactionSettlementInput<M extends AvAdapterModel> = {
|
|
38
|
+
readonly adapter: AvAdapter<M>;
|
|
39
|
+
/** The touched Resources' transaction levels, outer to inner. */
|
|
40
|
+
readonly levels: readonly ResolvedTransactionPipelineConfig[];
|
|
41
|
+
readonly plan: readonly TransactionStepView[];
|
|
42
|
+
/** The ctx a transaction stage is told, bound to the open transaction. */
|
|
43
|
+
readonly contextOf: (plan: readonly TransactionStepView[], executor: AvAdapterTransactionExecutor<M>) => AvTransactionContext;
|
|
44
|
+
/** What a stage failure's filters may read as the caller's arguments. */
|
|
45
|
+
readonly failureView: CallerArgumentsView;
|
|
46
|
+
/** The channel a transaction stage's own failure is reported on. */
|
|
47
|
+
readonly report: DiagnosticsReporter;
|
|
48
|
+
readonly runStep: TransactionStepRunner<M>;
|
|
49
|
+
};
|
|
50
|
+
/** Runs `plan` inside one Adapter transaction, its stages around its steps, and settles it. */
|
|
51
|
+
export declare function settleTransaction<M extends AvAdapterModel>(input: TransactionSettlementInput<M>): Promise<TransactionSettlement>;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { filterChain, resolveUnhandledFailure, sanitizeOperationFailure, } from "../runtime/error-boundary.js";
|
|
2
|
+
import { thrownFailure } from "../runtime/framework-error.factory.js";
|
|
3
|
+
import { operationFailure } from "../runtime/operation-response.js";
|
|
4
|
+
import { AvTransactionIntegrityError } from "./transaction-integrity-error.js";
|
|
5
|
+
import { resolveTransactionStageFailure, runTransactionStages, TRANSACTION_ABORT, } from "./transaction-stage.runtime.js";
|
|
6
|
+
export async function settleTransaction(input) {
|
|
7
|
+
const { adapter, levels, plan, contextOf } = input;
|
|
8
|
+
if (typeof adapter.transaction !== "function") {
|
|
9
|
+
return {
|
|
10
|
+
kind: "broken",
|
|
11
|
+
error: new AvTransactionIntegrityError("transaction-unavailable"),
|
|
12
|
+
operation: undefined,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const ledger = { results: [], responses: [], failure: undefined, deferred: undefined };
|
|
16
|
+
const { results, responses } = ledger;
|
|
17
|
+
const failedOperation = () => ledger.failure?.kind === "rolled-back"
|
|
18
|
+
? ledger.failure.operation
|
|
19
|
+
: undefined;
|
|
20
|
+
try {
|
|
21
|
+
await adapter.transaction(async (executor) => {
|
|
22
|
+
const staged = await runTransactionStages(levels, plan, (current) => contextOf(current, executor), async ({ plan: current, piped }) => {
|
|
23
|
+
const outer = {
|
|
24
|
+
defer: (failure) => {
|
|
25
|
+
ledger.deferred = { failure, plan: current };
|
|
26
|
+
return sanitizeOperationFailure(failure.error, failure.boundary.originOf(failure.error), () => { }, failure.view);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
for (const [index, step] of current.entries()) {
|
|
30
|
+
const response = await input.runStep(index, step, piped, executor, results, outer);
|
|
31
|
+
if (response.cause !== null) {
|
|
32
|
+
ledger.failure = {
|
|
33
|
+
kind: "rolled-back",
|
|
34
|
+
response,
|
|
35
|
+
operation: index,
|
|
36
|
+
};
|
|
37
|
+
throw thrownFailure(response);
|
|
38
|
+
}
|
|
39
|
+
results.push(response.data);
|
|
40
|
+
responses.push(response);
|
|
41
|
+
}
|
|
42
|
+
return [...results];
|
|
43
|
+
});
|
|
44
|
+
if (staged.kind === "broken") {
|
|
45
|
+
ledger.failure = { kind: "broken", error: staged.error };
|
|
46
|
+
throw TRANSACTION_ABORT;
|
|
47
|
+
}
|
|
48
|
+
const deferred = ledger.deferred;
|
|
49
|
+
if (deferred !== undefined && ledger.failure?.kind === "rolled-back") {
|
|
50
|
+
ledger.failure = {
|
|
51
|
+
...ledger.failure,
|
|
52
|
+
response: await resolveUnhandledFailure(deferred.failure, filterChain(levels.flatMap((level) => level.filters), contextOf(deferred.plan, executor))),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (staged.kind === "ran") {
|
|
56
|
+
if (ledger.failure === undefined && results.length !== plan.length) {
|
|
57
|
+
ledger.failure = {
|
|
58
|
+
kind: "broken",
|
|
59
|
+
error: new AvTransactionIntegrityError("steps-not-run"),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (ledger.failure !== undefined) {
|
|
63
|
+
throw TRANSACTION_ABORT;
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (ledger.failure === undefined) {
|
|
68
|
+
let response;
|
|
69
|
+
if (staged.kind === "denied") {
|
|
70
|
+
response = operationFailure("A4001", {
|
|
71
|
+
message: "Operation denied by a framework guard.",
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else if (staged.kind === "refused") {
|
|
75
|
+
input.report(staged.refusal.error, "A3004");
|
|
76
|
+
response = staged.refusal.response;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
response = await resolveTransactionStageFailure(staged.error, levels, contextOf(plan, executor), input.report, input.failureView);
|
|
80
|
+
}
|
|
81
|
+
ledger.failure = {
|
|
82
|
+
kind: "rolled-back",
|
|
83
|
+
response,
|
|
84
|
+
operation: undefined,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
throw TRANSACTION_ABORT;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (error !== TRANSACTION_ABORT) {
|
|
92
|
+
return { kind: "broken", error, operation: failedOperation() };
|
|
93
|
+
}
|
|
94
|
+
if (ledger.failure === undefined) {
|
|
95
|
+
return {
|
|
96
|
+
kind: "broken",
|
|
97
|
+
error: new AvTransactionIntegrityError("foreign-abort"),
|
|
98
|
+
operation: undefined,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return ledger.failure.kind === "broken"
|
|
102
|
+
? { kind: "broken", error: ledger.failure.error, operation: undefined }
|
|
103
|
+
: ledger.failure;
|
|
104
|
+
}
|
|
105
|
+
if (ledger.failure !== undefined) {
|
|
106
|
+
return {
|
|
107
|
+
kind: "broken",
|
|
108
|
+
error: new AvTransactionIntegrityError("resolved-after-abort"),
|
|
109
|
+
operation: failedOperation(),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (responses.length !== plan.length) {
|
|
113
|
+
return {
|
|
114
|
+
kind: "broken",
|
|
115
|
+
error: new AvTransactionIntegrityError("resolved-incomplete"),
|
|
116
|
+
operation: undefined,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return { kind: "committed", responses };
|
|
120
|
+
}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* The ways a transaction slot path can fail to name a member of its argument
|
|
3
3
|
* view. Each is a framework defect, not a caller error.
|
|
4
4
|
*/
|
|
5
|
-
export type
|
|
5
|
+
export type AvTransactionSlotPathViolation = "slot-prefix" | "absent-member" | "non-object-ancestor";
|
|
6
6
|
/**
|
|
7
7
|
* Thrown internally when a slot path does not name a member of its argument
|
|
8
8
|
* view; the caller receives `A3000`, and the diagnostics sink receives this
|
|
9
9
|
* error.
|
|
10
10
|
*/
|
|
11
|
-
export declare class
|
|
12
|
-
readonly violation:
|
|
13
|
-
constructor(violation:
|
|
11
|
+
export declare class AvTransactionSlotPathError extends Error {
|
|
12
|
+
readonly violation: AvTransactionSlotPathViolation;
|
|
13
|
+
constructor(violation: AvTransactionSlotPathViolation);
|
|
14
14
|
}
|
|
@@ -3,11 +3,11 @@ const TRANSACTION_SLOT_PATH_MESSAGES = {
|
|
|
3
3
|
"absent-member": "Transaction slot path names an absent member of the operation arguments.",
|
|
4
4
|
"non-object-ancestor": "Transaction slot path descends through a non-object value.",
|
|
5
5
|
};
|
|
6
|
-
export class
|
|
6
|
+
export class AvTransactionSlotPathError extends Error {
|
|
7
7
|
violation;
|
|
8
8
|
constructor(violation) {
|
|
9
9
|
super(TRANSACTION_SLOT_PATH_MESSAGES[violation]);
|
|
10
|
-
this.name = "
|
|
10
|
+
this.name = "AvTransactionSlotPathError";
|
|
11
11
|
this.violation = violation;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AvTransactionSlotPathError } from "./transaction-slot-path-error.js";
|
|
2
2
|
function slotPathMismatch(violation) {
|
|
3
|
-
throw new
|
|
3
|
+
throw new AvTransactionSlotPathError(violation);
|
|
4
4
|
}
|
|
5
5
|
function cloneContainerWithReplacement(container, property, replacement) {
|
|
6
6
|
const array = Array.isArray(container);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { ResolvedTransactionPipelineConfig } from "../config/pipeline-config.js";
|
|
2
|
+
import type { AvContract } from "../contracts/contract.js";
|
|
3
|
+
import type { ContextFacts } from "../runtime/context-executor.runtime.js";
|
|
4
|
+
import type { DiagnosticsReporter } from "../runtime/diagnostics-reporter.js";
|
|
5
|
+
import { type CallerArgumentsView } from "../runtime/error-boundary.js";
|
|
6
|
+
import type { OperationExecutionRequest } from "../runtime/operation-request.js";
|
|
7
|
+
import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
|
|
8
|
+
import { type RefusedStageOutput } from "../runtime/pipe-output.validator.js";
|
|
9
|
+
import type { AvTransactionContext, AvTransactionStep } from "../runtime/pipeline.js";
|
|
10
|
+
import { AvTransactionIntegrityError } from "./transaction-integrity-error.js";
|
|
11
|
+
/**
|
|
12
|
+
* The framework-owned rollback request. It is thrown out of the Adapter transaction
|
|
13
|
+
* callback only after a failure is recorded, and a rejection is recognized as it
|
|
14
|
+
* solely by identity — never by message, shape or class. It is a control signal,
|
|
15
|
+
* not a failure, so it never reaches diagnostics.
|
|
16
|
+
*/
|
|
17
|
+
export declare const TRANSACTION_ABORT: Readonly<{
|
|
18
|
+
readonly reason: "aventara-transaction-abort";
|
|
19
|
+
}>;
|
|
20
|
+
/** One plan step as a transaction stage reads it (the erased {@link AvTransactionStep}). */
|
|
21
|
+
export type TransactionStepView = AvTransactionStep;
|
|
22
|
+
/** The subject a refused transaction pipe output is reported under. */
|
|
23
|
+
export declare const TRANSACTION_PIPES = "Transaction pipes";
|
|
24
|
+
/**
|
|
25
|
+
* The `$` facts a transaction stage is told: the plan as `$args`, not one
|
|
26
|
+
* operation (`$operation` is absent). Each ctx holds its own frozen copy of the
|
|
27
|
+
* plan, a `Date` or a `Uint8Array` in a step's arguments fresh.
|
|
28
|
+
*/
|
|
29
|
+
export declare function transactionFacts(contract: AvContract, request: Pick<OperationExecutionRequest, "origin" | "requestId" | "transport">, plan: readonly TransactionStepView[]): ContextFacts;
|
|
30
|
+
/** How the transaction stages around a plan's steps ended. */
|
|
31
|
+
export type TransactionStagesOutcome =
|
|
32
|
+
/** Every stage and step ran; the steps' results, as the stages left them. */
|
|
33
|
+
{
|
|
34
|
+
readonly kind: "ran";
|
|
35
|
+
}
|
|
36
|
+
/** A transaction guard returned `false`: `A4001`. */
|
|
37
|
+
| {
|
|
38
|
+
readonly kind: "denied";
|
|
39
|
+
}
|
|
40
|
+
/** A transaction pipe returned something that is not the plan: `A3004`. */
|
|
41
|
+
| {
|
|
42
|
+
readonly kind: "refused";
|
|
43
|
+
readonly refusal: RefusedStageOutput;
|
|
44
|
+
}
|
|
45
|
+
/** A stage or a step threw (the rollback request included). */
|
|
46
|
+
| {
|
|
47
|
+
readonly kind: "failed";
|
|
48
|
+
readonly error: unknown;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A transaction interceptor broke the stages' contract: it called `next()`
|
|
52
|
+
* twice (whatever it then did with the refusal). Answered `A3002`, past every
|
|
53
|
+
* filter, and the transaction rolls back.
|
|
54
|
+
*/
|
|
55
|
+
| {
|
|
56
|
+
readonly kind: "broken";
|
|
57
|
+
readonly error: AvTransactionIntegrityError;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* What the steps see after the stages: the plan, and whether a transaction pipe
|
|
61
|
+
* changed it, in which case every operation step's arguments are held to the
|
|
62
|
+
* server's rules and its validators again before it runs.
|
|
63
|
+
*/
|
|
64
|
+
export type StagedPlan = {
|
|
65
|
+
readonly plan: readonly TransactionStepView[];
|
|
66
|
+
readonly piped: boolean;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Each touched Resource's transaction levels, root then overlay, Resources in the
|
|
70
|
+
* order their first top-level operation step appears. A SQL step touches nothing.
|
|
71
|
+
*/
|
|
72
|
+
export declare function touchedTransactionLevels(plan: readonly TransactionStepView[], levelsOf: (resource: string) => readonly ResolvedTransactionPipelineConfig[]): readonly ResolvedTransactionPipelineConfig[];
|
|
73
|
+
/**
|
|
74
|
+
* Runs the transaction stages of `levels` around `runSteps`, inside an open
|
|
75
|
+
* transaction. Never throws: every way the stages can end is the outcome.
|
|
76
|
+
*/
|
|
77
|
+
export declare function runTransactionStages(levels: readonly ResolvedTransactionPipelineConfig[], plan: readonly TransactionStepView[], contextOf: (plan: readonly TransactionStepView[]) => AvTransactionContext, runSteps: (staged: StagedPlan) => Promise<readonly unknown[]>): Promise<TransactionStagesOutcome>;
|
|
78
|
+
/**
|
|
79
|
+
* An error a transaction stage threw, through the touched Resources' filters in
|
|
80
|
+
* exact reverse (the first that handles it wins), then final sanitization.
|
|
81
|
+
*/
|
|
82
|
+
export declare function resolveTransactionStageFailure(error: unknown, levels: readonly ResolvedTransactionPipelineConfig[], context: AvTransactionContext, report: DiagnosticsReporter, view: CallerArgumentsView): Promise<AvOperationFailureResponse>;
|