@aventara/core 0.1.0-pilot.4 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/CHANGELOG.md +1478 -0
  2. package/README.md +275 -11
  3. package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
  4. package/dist/adapters/adapter-field.d.ts +11 -11
  5. package/dist/adapters/adapter-identifier.d.ts +6 -6
  6. package/dist/adapters/adapter-model.d.ts +17 -9
  7. package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
  8. package/dist/adapters/adapter-operation.d.ts +3 -3
  9. package/dist/adapters/adapter-resource.d.ts +18 -9
  10. package/dist/adapters/adapter-sql-statement.d.ts +19 -0
  11. package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
  12. package/dist/adapters/adapter.interface.d.ts +49 -25
  13. package/dist/avz/avz-check.factory.d.ts +83 -0
  14. package/dist/avz/avz-check.factory.js +116 -0
  15. package/dist/avz/avz-check.registry.d.ts +35 -0
  16. package/dist/avz/avz-check.registry.js +9 -0
  17. package/dist/avz/avz.d.ts +203 -0
  18. package/dist/avz/avz.js +354 -0
  19. package/dist/avz/index.d.ts +7 -0
  20. package/dist/avz/index.js +1 -0
  21. package/dist/avz/json-shape.registry.d.ts +22 -0
  22. package/dist/avz/json-shape.registry.js +16 -0
  23. package/dist/avz/zod-issue.translator.d.ts +57 -0
  24. package/dist/avz/zod-issue.translator.js +149 -0
  25. package/dist/compiler/contract-compiler-diagnostic.d.ts +37 -5
  26. package/dist/compiler/contract.compiler.d.ts +18 -18
  27. package/dist/compiler/contract.compiler.js +595 -421
  28. package/dist/compiler/create-requirements.projector.d.ts +49 -0
  29. package/dist/compiler/create-requirements.projector.js +423 -0
  30. package/dist/compiler/field-validator.compiler.d.ts +47 -0
  31. package/dist/compiler/field-validator.compiler.js +238 -0
  32. package/dist/config/any-framework-config.d.ts +19 -12
  33. package/dist/config/config-diagnostic.d.ts +11 -4
  34. package/dist/config/config-layer.d.ts +15 -6
  35. package/dist/config/config.resolver.d.ts +75 -29
  36. package/dist/config/config.resolver.js +109 -44
  37. package/dist/config/config.validator.d.ts +7 -7
  38. package/dist/config/config.validator.js +586 -71
  39. package/dist/config/define-resource.d.ts +57 -0
  40. package/dist/config/define-resource.js +14 -0
  41. package/dist/config/effective-fields.d.ts +19 -23
  42. package/dist/config/entrypoint.normalizer.d.ts +1 -1
  43. package/dist/config/exact-framework-config.d.ts +280 -0
  44. package/dist/config/field-compute.resolver.d.ts +19 -0
  45. package/dist/config/field-compute.resolver.js +115 -0
  46. package/dist/config/field-pipeline-config.d.ts +47 -0
  47. package/dist/config/forced-operation.validator.d.ts +10 -0
  48. package/dist/config/forced-operation.validator.js +66 -0
  49. package/dist/config/framework-config.d.ts +111 -37
  50. package/dist/config/framework-exemptions-config.d.ts +91 -0
  51. package/dist/config/framework-exemptions-config.js +1 -0
  52. package/dist/config/framework-field-definition.d.ts +78 -0
  53. package/dist/config/framework-field-definition.js +28 -0
  54. package/dist/config/framework-resources-config.d.ts +116 -0
  55. package/dist/config/framework-resources-config.js +1 -0
  56. package/dist/config/pipeline-config.d.ts +56 -20
  57. package/dist/config/pipeline-tree.resolver.d.ts +79 -0
  58. package/dist/config/pipeline-tree.resolver.js +220 -0
  59. package/dist/config/stage-type.eraser.d.ts +65 -0
  60. package/dist/config/stage-type.eraser.js +1 -0
  61. package/dist/contracts/capability.d.ts +11 -11
  62. package/dist/contracts/client-contract-structure.validator.d.ts +344 -29
  63. package/dist/contracts/client-contract-structure.validator.js +248 -7
  64. package/dist/contracts/contract-canonicalizer.d.ts +19 -3
  65. package/dist/contracts/contract-canonicalizer.js +172 -27
  66. package/dist/contracts/contract-hash.d.ts +12 -7
  67. package/dist/contracts/contract-hash.js +3 -2
  68. package/dist/contracts/contract-limits.d.ts +4 -1
  69. package/dist/contracts/contract-limits.js +1 -0
  70. package/dist/contracts/contract-lookup.d.ts +5 -5
  71. package/dist/contracts/contract-protocol.d.ts +4 -4
  72. package/dist/contracts/contract.d.ts +31 -16
  73. package/dist/contracts/create-requirements.d.ts +35 -0
  74. package/dist/contracts/create-requirements.js +1 -0
  75. package/dist/contracts/enum-definition.d.ts +1 -1
  76. package/dist/contracts/field-check.d.ts +101 -0
  77. package/dist/contracts/field-check.js +1 -0
  78. package/dist/contracts/field.d.ts +61 -41
  79. package/dist/contracts/identifier.d.ts +4 -4
  80. package/dist/contracts/json-shape.d.ts +76 -0
  81. package/dist/contracts/json-shape.js +1 -0
  82. package/dist/contracts/lifecycle-trait.d.ts +2 -2
  83. package/dist/contracts/reference-write-limit.d.ts +7 -0
  84. package/dist/contracts/reference-write-limit.js +1 -0
  85. package/dist/contracts/resource-operations.d.ts +28 -28
  86. package/dist/contracts/resource.d.ts +15 -9
  87. package/dist/contracts/scalar-value-type.d.ts +25 -14
  88. package/dist/contracts/scalar.d.ts +3 -3
  89. package/dist/contracts/transaction-capability.d.ts +1 -1
  90. package/dist/contracts/wire-scalar-format.d.ts +4 -4
  91. package/dist/framework/contract-view.d.ts +234 -63
  92. package/dist/framework/framework-construction.error.d.ts +10 -10
  93. package/dist/framework/framework-construction.error.js +2 -2
  94. package/dist/framework/framework.d.ts +50 -24
  95. package/dist/framework/framework.factory.d.ts +8 -6
  96. package/dist/framework/framework.factory.js +95 -32
  97. package/dist/framework/operation-facade.d.ts +123 -52
  98. package/dist/framework/operation-facade.js +9 -1
  99. package/dist/index.d.ts +55 -82
  100. package/dist/index.js +6 -26
  101. package/dist/internal.d.ts +40 -0
  102. package/dist/internal.js +18 -0
  103. package/dist/operations/operation-arguments.d.ts +316 -201
  104. package/dist/operations/operation-call.d.ts +27 -28
  105. package/dist/operations/operation-identity.d.ts +12 -10
  106. package/dist/operations/operation-identity.js +3 -0
  107. package/dist/operations/operation-result.d.ts +21 -21
  108. package/dist/operations/operation-validator-core.d.ts +6 -6
  109. package/dist/operations/operation-validator-core.js +41 -12
  110. package/dist/operations/operation-validator.d.ts +24 -9
  111. package/dist/operations/operation-validator.js +26 -10
  112. package/dist/operations/projection-scope.resolver.d.ts +7 -7
  113. package/dist/operations/structural-limits.walker.d.ts +19 -0
  114. package/dist/operations/structural-limits.walker.js +489 -0
  115. package/dist/operations/validation-code.d.ts +11 -6
  116. package/dist/operations/validation-code.js +4 -0
  117. package/dist/operations/write-scope.resolver.d.ts +6 -6
  118. package/dist/protocol/absent-route.responder.d.ts +13 -11
  119. package/dist/protocol/absent-route.responder.js +42 -16
  120. package/dist/protocol/contract-document.responder.d.ts +3 -3
  121. package/dist/protocol/contract-document.responder.js +2 -2
  122. package/dist/protocol/http-request.decoder.d.ts +23 -13
  123. package/dist/protocol/http-request.decoder.js +19 -11
  124. package/dist/protocol/http-request.reader.d.ts +3 -3
  125. package/dist/protocol/http-response.encoder.d.ts +4 -4
  126. package/dist/protocol/http-response.encoder.js +94 -55
  127. package/dist/protocol/http-status.table.d.ts +2 -2
  128. package/dist/protocol/operation-response.guard.d.ts +2 -2
  129. package/dist/protocol/protocol-surface.d.ts +4 -4
  130. package/dist/protocol/protocol.binder.d.ts +52 -27
  131. package/dist/protocol/protocol.binder.js +14 -9
  132. package/dist/protocol/protocol.handler.d.ts +28 -15
  133. package/dist/protocol/protocol.handler.js +55 -10
  134. package/dist/protocol/unmounted-route.error.d.ts +19 -0
  135. package/dist/protocol/unmounted-route.error.js +10 -0
  136. package/dist/runtime/caller-data.copier.d.ts +59 -0
  137. package/dist/runtime/caller-data.copier.js +470 -0
  138. package/dist/runtime/caller-data.door.d.ts +56 -0
  139. package/dist/runtime/caller-data.door.js +67 -0
  140. package/dist/runtime/computed-read-runtime.d.ts +7 -6
  141. package/dist/runtime/computed-read-runtime.js +61 -55
  142. package/dist/runtime/computed-value.error.d.ts +13 -0
  143. package/dist/runtime/computed-value.error.js +9 -0
  144. package/dist/runtime/context-executor.runtime.d.ts +59 -0
  145. package/dist/runtime/context-executor.runtime.js +275 -0
  146. package/dist/runtime/create-requirement.d.ts +22 -57
  147. package/dist/runtime/create-requirement.js +140 -37
  148. package/dist/runtime/decimal.d.ts +2 -2
  149. package/dist/runtime/decimal.js +1 -1
  150. package/dist/runtime/diagnostics-reporter.d.ts +64 -22
  151. package/dist/runtime/diagnostics-reporter.js +35 -4
  152. package/dist/runtime/error-boundary.d.ts +73 -8
  153. package/dist/runtime/error-boundary.js +104 -48
  154. package/dist/runtime/execution-options.d.ts +10 -2
  155. package/dist/runtime/field-check.evaluator.d.ts +29 -0
  156. package/dist/runtime/field-check.evaluator.js +521 -0
  157. package/dist/runtime/field-compute.d.ts +64 -0
  158. package/dist/runtime/field-compute.js +1 -0
  159. package/dist/runtime/field-stage.plan.d.ts +15 -0
  160. package/dist/runtime/field-stage.plan.js +27 -0
  161. package/dist/runtime/field-stage.runtime.d.ts +35 -0
  162. package/dist/runtime/field-stage.runtime.js +143 -0
  163. package/dist/runtime/field-validator.runtime.d.ts +11 -0
  164. package/dist/runtime/field-validator.runtime.js +87 -0
  165. package/dist/runtime/framework-error-class.table.d.ts +33 -0
  166. package/dist/runtime/framework-error-class.table.js +25 -0
  167. package/dist/runtime/framework-error.d.ts +79 -7
  168. package/dist/runtime/framework-error.factory.d.ts +4 -0
  169. package/dist/runtime/framework-error.factory.js +15 -0
  170. package/dist/runtime/framework-error.js +23 -2
  171. package/dist/runtime/interceptor-next.error.d.ts +5 -0
  172. package/dist/runtime/interceptor-next.error.js +6 -0
  173. package/dist/runtime/json-value.d.ts +3 -3
  174. package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
  175. package/dist/runtime/level-lifecycle.runtime.js +42 -0
  176. package/dist/runtime/misuse-reporter.d.ts +32 -0
  177. package/dist/runtime/misuse-reporter.js +19 -0
  178. package/dist/runtime/mutation-planner.d.ts +19 -10
  179. package/dist/runtime/mutation-planner.js +62 -36
  180. package/dist/runtime/nested-write.walker.d.ts +32 -0
  181. package/dist/runtime/nested-write.walker.js +73 -0
  182. package/dist/runtime/operation-request.d.ts +35 -15
  183. package/dist/runtime/operation-response.d.ts +17 -17
  184. package/dist/runtime/operation-runtime.d.ts +125 -30
  185. package/dist/runtime/operation-runtime.js +423 -83
  186. package/dist/runtime/outcome-mapper.d.ts +16 -5
  187. package/dist/runtime/outcome-mapper.js +35 -8
  188. package/dist/runtime/output-validator.d.ts +16 -6
  189. package/dist/runtime/output-validator.js +12 -1
  190. package/dist/runtime/owned-execution.registry.d.ts +13 -0
  191. package/dist/runtime/owned-execution.registry.js +7 -0
  192. package/dist/runtime/pipe-output.validator.d.ts +33 -18
  193. package/dist/runtime/pipe-output.validator.js +12 -12
  194. package/dist/runtime/pipeline.d.ts +202 -28
  195. package/dist/runtime/readonly-value.d.ts +32 -0
  196. package/dist/runtime/readonly-value.js +141 -0
  197. package/dist/runtime/referential-action.d.ts +7 -0
  198. package/dist/runtime/request-envelope.validator.d.ts +5 -0
  199. package/dist/runtime/request-envelope.validator.js +123 -0
  200. package/dist/runtime/request-id.d.ts +1 -1
  201. package/dist/runtime/request-state.d.ts +14 -0
  202. package/dist/runtime/request-state.js +1 -0
  203. package/dist/runtime/request-state.resolver.d.ts +12 -0
  204. package/dist/runtime/request-state.resolver.js +20 -0
  205. package/dist/runtime/scalar-runtime.d.ts +56 -13
  206. package/dist/runtime/scalar-runtime.js +167 -86
  207. package/dist/transactions/deferred-operation.d.ts +35 -20
  208. package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
  209. package/dist/transactions/operation-arguments-encoder.js +2 -2
  210. package/dist/transactions/sql-statement.d.ts +77 -0
  211. package/dist/transactions/sql-statement.js +47 -0
  212. package/dist/transactions/sql-statement.validator.d.ts +44 -0
  213. package/dist/transactions/sql-statement.validator.js +134 -0
  214. package/dist/transactions/transaction-envelope.d.ts +4 -4
  215. package/dist/transactions/transaction-integrity-error.d.ts +6 -6
  216. package/dist/transactions/transaction-integrity-error.js +5 -2
  217. package/dist/transactions/transaction-plan-assembler.d.ts +23 -9
  218. package/dist/transactions/transaction-plan-assembler.js +195 -82
  219. package/dist/transactions/transaction-plan-validator.d.ts +53 -21
  220. package/dist/transactions/transaction-plan-validator.js +246 -163
  221. package/dist/transactions/transaction-reference-collector.d.ts +30 -0
  222. package/dist/transactions/transaction-reference-collector.js +204 -0
  223. package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
  224. package/dist/transactions/transaction-reference-resolver.js +27 -10
  225. package/dist/transactions/transaction-reference-validator.d.ts +34 -4
  226. package/dist/transactions/transaction-reference-validator.js +82 -43
  227. package/dist/transactions/transaction-reference.d.ts +30 -58
  228. package/dist/transactions/transaction-request.d.ts +20 -7
  229. package/dist/transactions/transaction-response.d.ts +12 -7
  230. package/dist/transactions/transaction-response.js +24 -1
  231. package/dist/transactions/transaction-runtime.d.ts +11 -8
  232. package/dist/transactions/transaction-runtime.js +167 -50
  233. package/dist/transactions/transaction-settlement.runtime.d.ts +51 -0
  234. package/dist/transactions/transaction-settlement.runtime.js +120 -0
  235. package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
  236. package/dist/transactions/transaction-slot-path-error.js +2 -2
  237. package/dist/transactions/transaction-slot-writer.js +2 -2
  238. package/dist/transactions/transaction-stage.runtime.d.ts +81 -0
  239. package/dist/transactions/transaction-stage.runtime.js +123 -0
  240. package/package.json +18 -3
  241. package/src/runtime/field-check.evaluator.ts +720 -0
  242. package/dist/config/define-fields.d.ts +0 -35
  243. package/dist/config/define-fields.js +0 -3
  244. package/dist/config/framework-behaviors-config.d.ts +0 -30
  245. package/dist/config/framework-fields-config.d.ts +0 -36
  246. package/dist/config/framework-restrictions-config.d.ts +0 -142
  247. package/dist/operations/operation-boolean-nodes.d.ts +0 -11
  248. package/dist/operations/operation-boolean-nodes.js +0 -283
  249. package/dist/operations/operation-nesting.d.ts +0 -8
  250. package/dist/operations/operation-nesting.js +0 -307
  251. package/dist/runtime/field-behavior.d.ts +0 -48
  252. /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
  253. /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
  254. /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
  255. /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
@@ -1,26 +1,39 @@
1
1
  import type { ClientProtocolIdentity } from "../runtime/operation-request.js";
2
- import type { PipelineTransportContext } from "../runtime/pipeline.js";
2
+ import type { AvTransportContext } from "../runtime/pipeline.js";
3
+ import type { AvState } from "../runtime/request-state.js";
3
4
  type TransactionRequestBase = {
4
5
  readonly requestId: string;
5
6
  readonly plan: unknown;
7
+ /**
8
+ * The run's `ctx.$state`: every step's stages and the transaction stages share
9
+ * this one object. Omitted, it is a fresh `{}`.
10
+ */
11
+ readonly state?: AvState;
6
12
  };
7
13
  /** An in-process transaction request, run under the Application Contract. */
8
14
  export type ApplicationTransactionRequest = TransactionRequestBase & {
9
- readonly scope: "application";
15
+ readonly origin: "application";
10
16
  readonly protocol?: never;
11
17
  readonly transport?: never;
12
18
  };
13
19
  /** A remote transaction request, run under the Client Contract. */
14
20
  export type ClientTransactionRequest = TransactionRequestBase & {
15
- readonly scope: "client";
21
+ readonly origin: "client";
16
22
  readonly protocol: ClientProtocolIdentity;
17
- readonly transport?: PipelineTransportContext;
23
+ readonly transport?: AvTransportContext;
24
+ };
25
+ /** An AI agent's transaction request, run under the Agent Contract. */
26
+ export type AgentTransactionRequest = TransactionRequestBase & {
27
+ readonly origin: "agent";
28
+ readonly protocol: ClientProtocolIdentity;
29
+ readonly transport?: AvTransportContext;
18
30
  };
19
31
  /** One transaction request, as `framework.executeTransaction` takes it. */
20
- export type FrameworkTransactionRequest = ApplicationTransactionRequest | ClientTransactionRequest;
32
+ export type FrameworkTransactionRequest = ApplicationTransactionRequest | ClientTransactionRequest | AgentTransactionRequest;
21
33
  /**
22
34
  * The origin one plan operation runs under: its own layer's Contract, its own
23
- * pipelines, and — for a client step — the protocol identity it is accepted with.
35
+ * pipelines, and — for a client or agent step — the protocol identity it is
36
+ * accepted with.
24
37
  */
25
- export type TransactionOperationOrigin = Pick<ApplicationTransactionRequest, "scope"> | Pick<ClientTransactionRequest, "scope" | "protocol" | "transport">;
38
+ export type TransactionOperationOrigin = Pick<ApplicationTransactionRequest, "origin"> | Pick<ClientTransactionRequest, "origin" | "protocol" | "transport"> | Pick<AgentTransactionRequest, "origin" | "protocol" | "transport">;
26
39
  export {};
@@ -1,15 +1,20 @@
1
- import type { OperationFailureResponse } from "../runtime/operation-response.js";
1
+ import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
2
2
  /** A committed plan: each operation's final `data`, in plan order. */
3
- export type TransactionCommittedResponse<T = readonly unknown[]> = {
3
+ export type AvTransactionCommittedResponse<T = readonly unknown[]> = {
4
4
  readonly data: T;
5
5
  readonly code: "A1009";
6
6
  readonly cause: null;
7
7
  };
8
8
  /** What a transaction answers: committed (`A1009`) or a failure. */
9
- export type TransactionResponse = TransactionCommittedResponse | OperationFailureResponse;
9
+ export type AvTransactionResponse = AvTransactionCommittedResponse | AvOperationFailureResponse;
10
10
  /** Builds the committed response. */
11
- export declare function transactionCommitted(results: readonly unknown[]): TransactionCommittedResponse;
12
- /** Builds the failure response of a plan step, naming the step in `cause.operation`. */
13
- export declare function transactionOperationFailure(failure: OperationFailureResponse, operation: number): OperationFailureResponse;
11
+ export declare function transactionCommitted(results: readonly unknown[]): AvTransactionCommittedResponse;
12
+ /**
13
+ * Builds the failure response of a plan step: the step named in
14
+ * `cause.operation`, and each issue at its full plan location —
15
+ * `["operations", operation, "args", …]` for the step's arguments,
16
+ * `["operations", operation, …]` for the step itself.
17
+ */
18
+ export declare function transactionOperationFailure(failure: AvOperationFailureResponse, operation: number): AvOperationFailureResponse;
14
19
  /** Builds the `A3002` response for a transaction that itself failed. */
15
- export declare function transactionInfrastructureFailure(operation?: number): OperationFailureResponse;
20
+ export declare function transactionInfrastructureFailure(operation?: number): AvOperationFailureResponse;
@@ -1,13 +1,36 @@
1
+ import { OPERATION_ARGUMENTS_PATH, planOperationArgumentsPath, planStepPath, } from "../runtime/error-boundary.js";
1
2
  import { operationFailure } from "../runtime/operation-response.js";
2
3
  export function transactionCommitted(results) {
3
4
  return { data: results, code: "A1009", cause: null };
4
5
  }
5
6
  export function transactionOperationFailure(failure, operation) {
7
+ const { issues, ...cause } = failure.cause;
6
8
  return operationFailure(failure.code, {
7
- ...failure.cause,
9
+ ...cause,
10
+ ...(issues === undefined
11
+ ? {}
12
+ : { issues: issues.map((issue) => atPlanLocation(issue, operation)) }),
8
13
  operation,
9
14
  });
10
15
  }
16
+ function isPlanLocated(path) {
17
+ return path[0] === "operations" && typeof path[1] === "number";
18
+ }
19
+ function atPlanLocation(issue, operation) {
20
+ const { path } = issue;
21
+ if (path === undefined || isPlanLocated(path)) {
22
+ return issue;
23
+ }
24
+ return {
25
+ ...issue,
26
+ path: path[0] === OPERATION_ARGUMENTS_PATH[0]
27
+ ? [
28
+ ...planOperationArgumentsPath(operation),
29
+ ...path.slice(OPERATION_ARGUMENTS_PATH.length),
30
+ ]
31
+ : [...planStepPath(operation), ...path],
32
+ };
33
+ }
11
34
  export function transactionInfrastructureFailure(operation) {
12
35
  return operationFailure("A3002", {
13
36
  message: "Transaction failed.",
@@ -1,20 +1,23 @@
1
- import type { AdapterModel } from "../adapters/adapter-model.js";
1
+ import type { AvAdapterModel } from "../adapters/adapter-model.js";
2
2
  import type { TransactionDiagnosticsChannel } from "../runtime/diagnostics-reporter.js";
3
- import type { OperationRuntimeDependencies } from "../runtime/operation-runtime.js";
3
+ import type { OperationPipelineDependencies, OperationRuntimeDependencies } from "../runtime/operation-runtime.js";
4
+ import type { PlanArguments } from "./transaction-plan-validator.js";
4
5
  import type { FrameworkTransactionRequest, TransactionOperationOrigin } from "./transaction-request.js";
5
- import type { TransactionResponse } from "./transaction-response.js";
6
+ import type { AvTransactionResponse } from "./transaction-response.js";
6
7
  /**
7
8
  * The transaction executor core. Like the operation executor it owns no
8
9
  * diagnostics channel: the framework factory binds one to the request and
9
10
  * hands it in, so every report of a plan travels the same route.
10
11
  *
11
12
  * `origins`, when given, states each operation's own origin (the typed
12
- * runner's mixed plans); see `validateTransactionPlan`.
13
+ * runner's mixed plans), and `planArguments` whether the steps' arguments are
14
+ * copied at the door; see `validateTransactionPlan`.
13
15
  */
14
- export type FrameworkTransactionExecutor = (request: FrameworkTransactionRequest, diagnostics: TransactionDiagnosticsChannel, origins?: readonly TransactionOperationOrigin[]) => Promise<TransactionResponse>;
16
+ export type FrameworkTransactionExecutor = (request: FrameworkTransactionRequest, diagnostics: TransactionDiagnosticsChannel, origins: readonly TransactionOperationOrigin[] | undefined, planArguments: PlanArguments) => Promise<AvTransactionResponse>;
15
17
  /**
16
18
  * Validates a whole plan through the Framework Validation Layer, then runs it inside
17
- * exactly one Adapter transaction. Guards, pipes, hooks and interceptors of every plan
18
- * operation run while the provider transaction is open.
19
+ * exactly one Adapter transaction. The touched Resources' transaction stages and
20
+ * every plan operation's guards, pipes, hooks and interceptors run while the
21
+ * provider transaction is open.
19
22
  */
20
- export declare function createTransactionRuntime<M extends AdapterModel>(dependencies: OperationRuntimeDependencies<M>): FrameworkTransactionExecutor;
23
+ export declare function createTransactionRuntime<M extends AvAdapterModel>(dependencies: OperationRuntimeDependencies<M>, pipelineDependencies: OperationPipelineDependencies<M>): FrameworkTransactionExecutor;
@@ -1,80 +1,197 @@
1
- import { planOperationArgumentsPath } from "../runtime/error-boundary.js";
2
- import { internalFailure } from "../runtime/operation-response.js";
3
- import { executeValidatedOperation } from "../runtime/operation-runtime.js";
1
+ import { transactionLevelsOf } from "../config/pipeline-tree.resolver.js";
2
+ import { AdapterBoundary, planOperationArgumentsPath, planStepPath, sanitizeOperationFailure, } from "../runtime/error-boundary.js";
3
+ import { isPlainRecord, valueAt } from "../runtime/field-stage.runtime.js";
4
+ import { internalFailure, operationSuccess, } from "../runtime/operation-response.js";
5
+ import { admitOperation, executeAdmittedOperation, prepareStep, withRequestState, } from "../runtime/operation-runtime.js";
4
6
  import { mapValidationOutcome } from "../runtime/outcome-mapper.js";
5
7
  import { resolveCascadeClosure } from "../runtime/referential-action.js";
6
- import { TransactionIntegrityError } from "./transaction-integrity-error.js";
8
+ import { AvTransactionIntegrityError } from "./transaction-integrity-error.js";
7
9
  import { validateTransactionPlan } from "./transaction-plan-validator.js";
8
- import { resolveTransactionReferences } from "./transaction-reference-resolver.js";
10
+ import { resolveSqlStatement, resolveTransactionReferences, } from "./transaction-reference-resolver.js";
9
11
  import { transactionCommitted, transactionInfrastructureFailure, transactionOperationFailure, } from "./transaction-response.js";
10
- const TRANSACTION_ABORT = Object.freeze({ reason: "aventara-transaction-abort" });
11
- export function createTransactionRuntime(dependencies) {
12
- const { adapter, ...runtimeDependencies } = dependencies;
13
- const pipelineDependencies = {
14
- ...runtimeDependencies,
15
- createRequirements: adapter.createRequirements ?? {},
16
- };
12
+ import { settleTransaction } from "./transaction-settlement.runtime.js";
13
+ import { touchedTransactionLevels, transactionFacts, } from "./transaction-stage.runtime.js";
14
+ export function createTransactionRuntime(dependencies, pipelineDependencies) {
15
+ const { adapter } = dependencies;
17
16
  const planDependencies = {
18
17
  ...pipelineDependencies,
19
18
  cascades: resolveCascadeClosure(adapter.referentialActions),
19
+ sqlStatements: adapter.sqlStatements === true,
20
20
  };
21
- return async (request, diagnostics, origins) => {
22
- const validation = await validateTransactionPlan(planDependencies, request, origins);
21
+ return async (seeded, diagnostics, origins, planArguments) => {
22
+ const request = withRequestState(seeded);
23
+ const validation = await validateTransactionPlan(planDependencies, request, origins, planArguments);
23
24
  if (!validation.ok) {
24
25
  return validation.response;
25
26
  }
26
- return executeTransactionPlan(adapter, pipelineDependencies, validation.plan, diagnostics);
27
+ return executeTransactionPlan(adapter, pipelineDependencies, request, validation.plan, request.state, diagnostics);
27
28
  };
28
29
  }
29
- async function executeTransactionPlan(adapter, dependencies, plan, diagnostics) {
30
- const ledger = { results: [], failure: undefined };
31
- const infrastructureFailure = (error) => {
32
- const operation = ledger.failure?.operation;
33
- diagnostics.transaction(operation)(error, "A3002");
34
- return transactionInfrastructureFailure(operation);
30
+ function planOrigin(request, plan) {
31
+ for (const step of plan.operations) {
32
+ if (step.kind === "operation") {
33
+ return step.request;
34
+ }
35
+ }
36
+ return request;
37
+ }
38
+ function stepView(step, args) {
39
+ if (step.kind === "sql") {
40
+ return {
41
+ sql: {
42
+ strings: step.strings,
43
+ values: step.values.map((value) => value.kind === "value"
44
+ ? value.value
45
+ : { $ref: { operation: value.operation, path: [value.field] } }),
46
+ },
47
+ };
48
+ }
49
+ return {
50
+ resource: step.request.resource,
51
+ family: step.request.family,
52
+ variant: step.request.variant,
53
+ args,
35
54
  };
36
- if (typeof adapter.transaction !== "function") {
37
- return infrastructureFailure(new TransactionIntegrityError("transaction-unavailable"));
55
+ }
56
+ function pathKey(path) {
57
+ return JSON.stringify(path);
58
+ }
59
+ function relativeSlotPath(operation, path) {
60
+ return path.slice(planOperationArgumentsPath(operation.index).length);
61
+ }
62
+ function standsAt(args, path, slot) {
63
+ const value = valueAt(args, path);
64
+ if (value === slot.reference) {
65
+ return true;
38
66
  }
39
- const runPlanOperation = async (operation, executor) => {
67
+ const reference = isPlainRecord(value) ? value.$ref : undefined;
68
+ if (!isPlainRecord(reference) || !Array.isArray(reference.path)) {
69
+ return false;
70
+ }
71
+ const expected = slot.reference.$ref;
72
+ return (reference.operation === expected.operation &&
73
+ reference.path.length === 1 &&
74
+ reference.path[0] === expected.path[0]);
75
+ }
76
+ function slotKeys(operation) {
77
+ return new Set(operation.references.map((slot) => pathKey(relativeSlotPath(operation, slot.path))));
78
+ }
79
+ async function executeTransactionPlan(adapter, dependencies, request, plan, state, diagnostics) {
80
+ const stateful = (operation) => ({ ...operation.request, state });
81
+ const admitted = [];
82
+ for (const step of plan.operations) {
83
+ if (step.kind === "sql") {
84
+ admitted.push({ ok: true, args: undefined, piped: false });
85
+ continue;
86
+ }
87
+ const references = slotKeys(step);
88
+ const admission = await admitOperation(dependencies, stateful(step), step.contract, step.arguments, planOperationArgumentsPath(step.index), diagnostics.operation(step.request, step.index), { requestId: request.requestId, transaction: undefined, state }, {
89
+ select: (path) => !references.has(pathKey(path)),
90
+ validation: { transactionReferences: true },
91
+ });
92
+ if (!admission.ok) {
93
+ return transactionOperationFailure(admission.response, step.index);
94
+ }
95
+ admitted.push(admission);
96
+ }
97
+ const origin = planOrigin(request, plan);
98
+ const contract = dependencies.contracts[origin.origin];
99
+ const tree = dependencies.config[origin.origin].pipelines;
100
+ const view = plan.operations.map((step, index) => stepView(step, admitted[index]?.args));
101
+ const runPlanOperation = async (operation, args, transactionPiped, executor, results, outer) => {
40
102
  const report = diagnostics.operation(operation.request, operation.index);
103
+ const argumentsPath = planOperationArgumentsPath(operation.index);
104
+ const stepRequest = stateful(operation);
41
105
  try {
42
- const resolved = resolveTransactionReferences(operation, ledger.results);
106
+ const live = operation.references.filter((slot) => standsAt(args, relativeSlotPath(operation, slot.path), slot));
107
+ const resolved = resolveTransactionReferences({
108
+ ...operation,
109
+ arguments: args,
110
+ references: live,
111
+ }, results);
43
112
  if (!resolved.ok) {
44
113
  return mapValidationOutcome(resolved.issues);
45
114
  }
46
- return await executeValidatedOperation(dependencies, operation.request, operation.contract, resolved.arguments, planOperationArgumentsPath(operation.index), executor, report);
115
+ const written = new Set(live
116
+ .filter((slot) => slot.written)
117
+ .map((slot) => pathKey(relativeSlotPath(operation, slot.path))));
118
+ const prepared = await prepareStep(dependencies, stepRequest, operation.contract, resolved.arguments, argumentsPath, report, executor, {
119
+ written: (path) => written.has(pathKey(path)),
120
+ transactionPiped,
121
+ pipedAroundReferences: admitted[operation.index]?.piped === true &&
122
+ operation.references.length > 0,
123
+ }, outer);
124
+ if (!prepared.ok) {
125
+ return prepared.response;
126
+ }
127
+ return await executeAdmittedOperation(dependencies, stepRequest, operation.contract, prepared.args, argumentsPath, { kind: "transaction", executor, outer }, report);
47
128
  }
48
129
  catch (error) {
49
130
  report(error, "A3000");
50
131
  return internalFailure();
51
132
  }
52
133
  };
53
- try {
54
- await adapter.transaction(async (executor) => {
55
- for (const operation of plan.operations) {
56
- const response = await runPlanOperation(operation, executor);
57
- if (response.cause !== null) {
58
- ledger.failure = { response, operation: operation.index };
59
- throw TRANSACTION_ABORT;
60
- }
61
- ledger.results.push(response.data);
134
+ const runSqlStatement = async (step, executor, results) => {
135
+ const report = diagnostics.transaction(step.index);
136
+ const boundary = new AdapterBoundary();
137
+ try {
138
+ const resolved = resolveSqlStatement(step, results);
139
+ if (!resolved.ok) {
140
+ return mapValidationOutcome(resolved.issues);
141
+ }
142
+ if (typeof executor.executeSql !== "function") {
143
+ report(new AvTransactionIntegrityError("statement-unavailable"), "A3002");
144
+ return transactionInfrastructureFailure();
145
+ }
146
+ const executeSql = executor.executeSql.bind(executor);
147
+ try {
148
+ const rows = await boundary.execute(async () => {
149
+ const answer = await executeSql(resolved.statement);
150
+ if (!Array.isArray(answer)) {
151
+ throw new TypeError("Adapter executeSql must resolve the statement's rows as an array.");
152
+ }
153
+ return answer;
154
+ });
155
+ return operationSuccess([...rows], "A1000");
156
+ }
157
+ catch (error) {
158
+ return sanitizeOperationFailure(error, boundary.originOf(error), report, {
159
+ path: [...planStepPath(step.index), "values"],
160
+ arguments: resolved.statement.values,
161
+ });
62
162
  }
63
- });
64
- }
65
- catch (error) {
66
- if (error !== TRANSACTION_ABORT) {
67
- return infrastructureFailure(error);
68
163
  }
69
- return ledger.failure === undefined
70
- ? infrastructureFailure(new TransactionIntegrityError("foreign-abort"))
71
- : transactionOperationFailure(ledger.failure.response, ledger.failure.operation);
72
- }
73
- if (ledger.failure !== undefined) {
74
- return infrastructureFailure(new TransactionIntegrityError("resolved-after-abort"));
75
- }
76
- if (ledger.results.length !== plan.operations.length) {
77
- return infrastructureFailure(new TransactionIntegrityError("resolved-incomplete"));
164
+ catch (error) {
165
+ report(error, "A3000");
166
+ return internalFailure();
167
+ }
168
+ };
169
+ const settled = await settleTransaction({
170
+ adapter,
171
+ levels: touchedTransactionLevels(view, (resource) => transactionLevelsOf(tree, resource)),
172
+ plan: view,
173
+ contextOf: (current, executor) => dependencies.contexts.transaction({ requestId: origin.requestId, transaction: executor, state }, transactionFacts(contract, origin, current)),
174
+ failureView: { path: ["operations"], arguments: view },
175
+ report: diagnostics.transaction(),
176
+ runStep: (index, step, piped, executor, results, outer) => {
177
+ const operation = plan.operations[index];
178
+ if (operation === undefined) {
179
+ throw new TypeError(`Transaction step ${index} is not in the plan.`);
180
+ }
181
+ return operation.kind === "sql"
182
+ ? runSqlStatement(operation, executor, results)
183
+ : runPlanOperation(operation, step.args, piped, executor, results, outer);
184
+ },
185
+ });
186
+ switch (settled.kind) {
187
+ case "committed":
188
+ return transactionCommitted(settled.responses.map((response) => response.data));
189
+ case "rolled-back":
190
+ return settled.operation === undefined
191
+ ? settled.response
192
+ : transactionOperationFailure(settled.response, settled.operation);
193
+ case "broken":
194
+ diagnostics.transaction(settled.operation)(settled.error, "A3002");
195
+ return transactionInfrastructureFailure(settled.operation);
78
196
  }
79
- return transactionCommitted([...ledger.results]);
80
197
  }
@@ -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 TransactionSlotPathViolation = "slot-prefix" | "absent-member" | "non-object-ancestor";
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 TransactionSlotPathError extends Error {
12
- readonly violation: TransactionSlotPathViolation;
13
- constructor(violation: TransactionSlotPathViolation);
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 TransactionSlotPathError extends Error {
6
+ export class AvTransactionSlotPathError extends Error {
7
7
  violation;
8
8
  constructor(violation) {
9
9
  super(TRANSACTION_SLOT_PATH_MESSAGES[violation]);
10
- this.name = "TransactionSlotPathError";
10
+ this.name = "AvTransactionSlotPathError";
11
11
  this.violation = violation;
12
12
  }
13
13
  }
@@ -1,6 +1,6 @@
1
- import { TransactionSlotPathError } from "./transaction-slot-path-error.js";
1
+ import { AvTransactionSlotPathError } from "./transaction-slot-path-error.js";
2
2
  function slotPathMismatch(violation) {
3
- throw new TransactionSlotPathError(violation);
3
+ throw new AvTransactionSlotPathError(violation);
4
4
  }
5
5
  function cloneContainerWithReplacement(container, property, replacement) {
6
6
  const array = Array.isArray(container);