@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.
Files changed (267) hide show
  1. package/CHANGELOG.md +1434 -0
  2. package/ERRORS.md +142 -0
  3. package/README.md +247 -57
  4. package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
  5. package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
  6. package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
  7. package/dist/adapters/adapter-field.d.ts +25 -11
  8. package/dist/adapters/adapter-identifier.d.ts +6 -6
  9. package/dist/adapters/adapter-model.d.ts +18 -9
  10. package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
  11. package/dist/adapters/adapter-operation.d.ts +3 -3
  12. package/dist/adapters/adapter-resource.d.ts +18 -9
  13. package/dist/adapters/adapter-sql-statement.d.ts +19 -0
  14. package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
  15. package/dist/adapters/adapter.interface.d.ts +59 -29
  16. package/dist/avz/avz-check.factory.d.ts +83 -0
  17. package/dist/avz/avz-check.factory.js +116 -0
  18. package/dist/avz/avz-check.registry.d.ts +35 -0
  19. package/dist/avz/avz-check.registry.js +9 -0
  20. package/dist/avz/avz.d.ts +203 -0
  21. package/dist/{json → avz}/avz.js +150 -8
  22. package/dist/{json → avz}/index.d.ts +2 -1
  23. package/dist/{json → avz}/json-shape.registry.d.ts +7 -7
  24. package/dist/{json → avz}/zod-issue.translator.d.ts +8 -2
  25. package/dist/{json → avz}/zod-issue.translator.js +7 -0
  26. package/dist/compiler/contract-compiler-diagnostic.d.ts +31 -5
  27. package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
  28. package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
  29. package/dist/compiler/contract.compiler.d.ts +18 -18
  30. package/dist/compiler/contract.compiler.js +637 -442
  31. package/dist/compiler/create-requirements.projector.d.ts +49 -0
  32. package/dist/compiler/create-requirements.projector.js +423 -0
  33. package/dist/compiler/field-validator.compiler.d.ts +47 -0
  34. package/dist/compiler/field-validator.compiler.js +238 -0
  35. package/dist/config/any-framework-config.d.ts +19 -12
  36. package/dist/config/computed-fields.d.ts +62 -0
  37. package/dist/config/computed-fields.js +80 -0
  38. package/dist/config/config-diagnostic.d.ts +11 -4
  39. package/dist/config/config-diagnostic.guidance.d.ts +6 -0
  40. package/dist/config/config-diagnostic.guidance.js +32 -0
  41. package/dist/config/config-layer.d.ts +15 -6
  42. package/dist/config/config.resolver.d.ts +74 -31
  43. package/dist/config/config.resolver.js +108 -44
  44. package/dist/config/config.validator.d.ts +7 -7
  45. package/dist/config/config.validator.js +581 -72
  46. package/dist/config/define-resource.d.ts +57 -0
  47. package/dist/config/define-resource.js +14 -0
  48. package/dist/config/effective-fields.d.ts +19 -23
  49. package/dist/config/entrypoint.normalizer.d.ts +1 -1
  50. package/dist/config/exact-framework-config.d.ts +308 -0
  51. package/dist/config/field-compute.resolver.d.ts +21 -0
  52. package/dist/config/field-compute.resolver.js +123 -0
  53. package/dist/config/field-pipeline-config.d.ts +47 -0
  54. package/dist/config/forced-operation.validator.d.ts +10 -0
  55. package/dist/config/forced-operation.validator.js +66 -0
  56. package/dist/config/framework-config.d.ts +111 -39
  57. package/dist/config/framework-exemptions-config.d.ts +91 -0
  58. package/dist/config/framework-exemptions-config.js +1 -0
  59. package/dist/config/framework-field-definition.d.ts +78 -0
  60. package/dist/config/framework-field-definition.js +28 -0
  61. package/dist/config/framework-resources-config.d.ts +122 -0
  62. package/dist/config/framework-resources-config.js +1 -0
  63. package/dist/config/pipeline-config.d.ts +56 -20
  64. package/dist/config/pipeline-tree.resolver.d.ts +79 -0
  65. package/dist/config/pipeline-tree.resolver.js +220 -0
  66. package/dist/config/stage-type.eraser.d.ts +65 -0
  67. package/dist/config/stage-type.eraser.js +1 -0
  68. package/dist/contracts/capability.d.ts +21 -12
  69. package/dist/contracts/capability.js +2 -0
  70. package/dist/contracts/client-contract-structure.validator.d.ts +388 -63
  71. package/dist/contracts/client-contract-structure.validator.js +156 -10
  72. package/dist/contracts/contract-canonicalizer.d.ts +26 -3
  73. package/dist/contracts/contract-canonicalizer.js +156 -29
  74. package/dist/contracts/contract-hash.d.ts +12 -7
  75. package/dist/contracts/contract-hash.js +3 -2
  76. package/dist/contracts/contract-limits.d.ts +4 -1
  77. package/dist/contracts/contract-limits.js +1 -0
  78. package/dist/contracts/contract-lookup.d.ts +5 -5
  79. package/dist/contracts/contract-protocol.d.ts +4 -4
  80. package/dist/contracts/contract.d.ts +24 -16
  81. package/dist/contracts/create-requirements.d.ts +35 -0
  82. package/dist/contracts/create-requirements.js +1 -0
  83. package/dist/contracts/enum-definition.d.ts +1 -1
  84. package/dist/contracts/field-check.d.ts +101 -0
  85. package/dist/contracts/field-check.js +1 -0
  86. package/dist/contracts/field.d.ts +81 -42
  87. package/dist/contracts/identifier.d.ts +4 -4
  88. package/dist/contracts/json-shape.d.ts +12 -1
  89. package/dist/contracts/lifecycle-trait.d.ts +2 -2
  90. package/dist/contracts/resource-operations.d.ts +28 -28
  91. package/dist/contracts/resource.d.ts +15 -9
  92. package/dist/contracts/scalar-value-type.d.ts +15 -15
  93. package/dist/contracts/scalar.d.ts +3 -3
  94. package/dist/contracts/transaction-capability.d.ts +1 -1
  95. package/dist/contracts/wire-scalar-format.d.ts +4 -4
  96. package/dist/framework/contract-view.d.ts +213 -147
  97. package/dist/framework/framework-construction.error.d.ts +19 -10
  98. package/dist/framework/framework-construction.error.js +7 -3
  99. package/dist/framework/framework.d.ts +47 -23
  100. package/dist/framework/framework.factory.d.ts +8 -6
  101. package/dist/framework/framework.factory.js +49 -22
  102. package/dist/framework/operation-facade.d.ts +123 -52
  103. package/dist/framework/operation-facade.js +9 -1
  104. package/dist/index.d.ts +57 -50
  105. package/dist/index.js +7 -6
  106. package/dist/internal.d.ts +17 -10
  107. package/dist/internal.js +4 -1
  108. package/dist/operations/database-refusal.d.ts +51 -0
  109. package/dist/operations/database-refusal.js +45 -0
  110. package/dist/operations/operation-arguments.d.ts +343 -207
  111. package/dist/operations/operation-call.d.ts +27 -28
  112. package/dist/operations/operation-identity.d.ts +10 -10
  113. package/dist/operations/operation-result.d.ts +21 -21
  114. package/dist/operations/operation-validator-core.d.ts +6 -6
  115. package/dist/operations/operation-validator-core.js +99 -6
  116. package/dist/operations/operation-validator.d.ts +9 -9
  117. package/dist/operations/projection-scope.resolver.d.ts +6 -6
  118. package/dist/operations/structural-limits.walker.d.ts +6 -6
  119. package/dist/operations/structural-limits.walker.js +145 -0
  120. package/dist/operations/validation-code.d.ts +11 -6
  121. package/dist/operations/validation-code.guidance.d.ts +6 -0
  122. package/dist/operations/validation-code.guidance.js +90 -0
  123. package/dist/operations/validation-code.js +4 -0
  124. package/dist/operations/write-scope.resolver.d.ts +10 -6
  125. package/dist/operations/write-scope.resolver.js +2 -0
  126. package/dist/protocol/absent-route.responder.d.ts +13 -12
  127. package/dist/protocol/absent-route.responder.js +19 -19
  128. package/dist/protocol/contract-document.responder.d.ts +3 -3
  129. package/dist/protocol/contract-document.responder.js +2 -2
  130. package/dist/protocol/http-request.decoder.d.ts +17 -13
  131. package/dist/protocol/http-request.decoder.js +10 -10
  132. package/dist/protocol/http-request.reader.d.ts +3 -3
  133. package/dist/protocol/http-response.encoder.d.ts +4 -4
  134. package/dist/protocol/http-response.encoder.js +94 -55
  135. package/dist/protocol/http-status.table.d.ts +2 -2
  136. package/dist/protocol/operation-response.guard.d.ts +2 -2
  137. package/dist/protocol/protocol-surface.d.ts +4 -4
  138. package/dist/protocol/protocol.binder.d.ts +50 -27
  139. package/dist/protocol/protocol.binder.js +12 -9
  140. package/dist/protocol/protocol.handler.d.ts +22 -13
  141. package/dist/protocol/protocol.handler.js +91 -17
  142. package/dist/protocol/unmounted-route.error.d.ts +4 -4
  143. package/dist/protocol/unmounted-route.error.js +2 -2
  144. package/dist/runtime/caller-data.copier.d.ts +22 -5
  145. package/dist/runtime/caller-data.copier.js +31 -14
  146. package/dist/runtime/caller-data.door.d.ts +17 -11
  147. package/dist/runtime/caller-data.door.js +6 -4
  148. package/dist/runtime/computed-read-runtime.d.ts +7 -6
  149. package/dist/runtime/computed-read-runtime.js +76 -50
  150. package/dist/runtime/computed-value.error.d.ts +7 -6
  151. package/dist/runtime/computed-value.error.js +5 -4
  152. package/dist/runtime/context-executor.runtime.d.ts +59 -0
  153. package/dist/runtime/context-executor.runtime.js +275 -0
  154. package/dist/runtime/create-requirement.d.ts +44 -79
  155. package/dist/runtime/create-requirement.js +213 -73
  156. package/dist/runtime/decimal.d.ts +2 -2
  157. package/dist/runtime/decimal.js +1 -1
  158. package/dist/runtime/diagnostics-reporter.d.ts +54 -27
  159. package/dist/runtime/diagnostics-reporter.js +24 -0
  160. package/dist/runtime/error-boundary.d.ts +65 -8
  161. package/dist/runtime/error-boundary.js +49 -19
  162. package/dist/runtime/error-guidance.d.ts +12 -0
  163. package/dist/runtime/error-guidance.js +1 -0
  164. package/dist/runtime/error.catalog.d.ts +49 -0
  165. package/dist/runtime/error.catalog.js +49 -0
  166. package/dist/runtime/execution-options.d.ts +10 -2
  167. package/dist/runtime/field-check.evaluator.d.ts +29 -0
  168. package/dist/runtime/field-check.evaluator.js +521 -0
  169. package/dist/runtime/field-compute.d.ts +64 -0
  170. package/dist/runtime/field-compute.js +1 -0
  171. package/dist/runtime/field-stage.plan.d.ts +15 -0
  172. package/dist/runtime/field-stage.plan.js +27 -0
  173. package/dist/runtime/field-stage.runtime.d.ts +37 -0
  174. package/dist/runtime/field-stage.runtime.js +147 -0
  175. package/dist/runtime/field-validator.runtime.d.ts +19 -0
  176. package/dist/runtime/field-validator.runtime.js +92 -0
  177. package/dist/runtime/framework-error-class.table.d.ts +33 -0
  178. package/dist/runtime/framework-error-class.table.js +25 -0
  179. package/dist/runtime/framework-error.d.ts +68 -8
  180. package/dist/runtime/framework-error.factory.d.ts +4 -0
  181. package/dist/runtime/framework-error.factory.js +15 -0
  182. package/dist/runtime/framework-error.js +23 -2
  183. package/dist/runtime/interceptor-next.error.d.ts +5 -0
  184. package/dist/runtime/interceptor-next.error.js +6 -0
  185. package/dist/runtime/json-value.d.ts +11 -6
  186. package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
  187. package/dist/runtime/level-lifecycle.runtime.js +39 -0
  188. package/dist/runtime/misuse-reporter.d.ts +12 -12
  189. package/dist/runtime/mutation-planner.d.ts +19 -10
  190. package/dist/runtime/mutation-planner.js +48 -35
  191. package/dist/runtime/nested-write.walker.d.ts +32 -0
  192. package/dist/runtime/nested-write.walker.js +73 -0
  193. package/dist/runtime/operation-code.guidance.d.ts +6 -0
  194. package/dist/runtime/operation-code.guidance.js +167 -0
  195. package/dist/runtime/operation-request.d.ts +33 -6
  196. package/dist/runtime/operation-response.d.ts +17 -17
  197. package/dist/runtime/operation-runtime.d.ts +127 -25
  198. package/dist/runtime/operation-runtime.js +441 -78
  199. package/dist/runtime/outcome-mapper.d.ts +16 -5
  200. package/dist/runtime/outcome-mapper.js +23 -6
  201. package/dist/runtime/output-validator.d.ts +10 -10
  202. package/dist/runtime/output-validator.js +3 -3
  203. package/dist/runtime/owned-execution.registry.d.ts +16 -6
  204. package/dist/runtime/pipe-output.validator.d.ts +43 -18
  205. package/dist/runtime/pipe-output.validator.js +15 -13
  206. package/dist/runtime/pipeline.d.ts +223 -34
  207. package/dist/runtime/readonly-value.d.ts +43 -0
  208. package/dist/runtime/readonly-value.js +150 -0
  209. package/dist/runtime/request-envelope.validator.d.ts +3 -3
  210. package/dist/runtime/request-envelope.validator.js +12 -7
  211. package/dist/runtime/request-id.d.ts +1 -1
  212. package/dist/runtime/request-state.d.ts +14 -0
  213. package/dist/runtime/request-state.js +1 -0
  214. package/dist/runtime/request-state.resolver.d.ts +12 -0
  215. package/dist/runtime/request-state.resolver.js +20 -0
  216. package/dist/runtime/scalar-runtime.d.ts +35 -16
  217. package/dist/runtime/scalar-runtime.js +102 -34
  218. package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
  219. package/dist/runtime/unsent-value.normalizer.js +128 -0
  220. package/dist/transactions/deferred-operation.d.ts +35 -20
  221. package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
  222. package/dist/transactions/operation-arguments-encoder.js +2 -2
  223. package/dist/transactions/operation-fingerprint.js +2 -2
  224. package/dist/transactions/sql-statement.d.ts +85 -0
  225. package/dist/transactions/sql-statement.js +47 -0
  226. package/dist/transactions/sql-statement.validator.d.ts +44 -0
  227. package/dist/transactions/sql-statement.validator.js +167 -0
  228. package/dist/transactions/transaction-envelope.d.ts +4 -4
  229. package/dist/transactions/transaction-integrity-error.d.ts +6 -6
  230. package/dist/transactions/transaction-integrity-error.js +5 -2
  231. package/dist/transactions/transaction-plan-assembler.d.ts +21 -11
  232. package/dist/transactions/transaction-plan-assembler.js +169 -32
  233. package/dist/transactions/transaction-plan-validator.d.ts +45 -20
  234. package/dist/transactions/transaction-plan-validator.js +96 -38
  235. package/dist/transactions/transaction-reference-collector.d.ts +5 -5
  236. package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
  237. package/dist/transactions/transaction-reference-resolver.js +26 -14
  238. package/dist/transactions/transaction-reference-validator.d.ts +76 -4
  239. package/dist/transactions/transaction-reference-validator.js +129 -71
  240. package/dist/transactions/transaction-reference.d.ts +13 -13
  241. package/dist/transactions/transaction-reference.js +5 -0
  242. package/dist/transactions/transaction-request.d.ts +18 -5
  243. package/dist/transactions/transaction-response.d.ts +6 -6
  244. package/dist/transactions/transaction-runtime.d.ts +8 -7
  245. package/dist/transactions/transaction-runtime.js +191 -50
  246. package/dist/transactions/transaction-settlement.runtime.d.ts +51 -0
  247. package/dist/transactions/transaction-settlement.runtime.js +120 -0
  248. package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
  249. package/dist/transactions/transaction-slot-path-error.js +2 -2
  250. package/dist/transactions/transaction-slot-writer.js +2 -2
  251. package/dist/transactions/transaction-stage.runtime.d.ts +82 -0
  252. package/dist/transactions/transaction-stage.runtime.js +126 -0
  253. package/package.json +9 -7
  254. package/src/runtime/field-check.evaluator.ts +720 -0
  255. package/dist/config/define-fields.d.ts +0 -42
  256. package/dist/config/define-fields.js +0 -3
  257. package/dist/config/framework-behaviors-config.d.ts +0 -30
  258. package/dist/config/framework-fields-config.d.ts +0 -42
  259. package/dist/config/framework-restrictions-config.d.ts +0 -142
  260. package/dist/json/avz.d.ts +0 -96
  261. package/dist/runtime/field-behavior.d.ts +0 -48
  262. /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
  263. /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
  264. /package/dist/{json → avz}/index.js +0 -0
  265. /package/dist/{json → avz}/json-shape.registry.js +0 -0
  266. /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
  267. /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
@@ -1,16 +1,15 @@
1
1
  import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
2
- import { ComputedValueError } from "./computed-value.error.js";
2
+ import { AvComputedValueError } from "./computed-value.error.js";
3
+ import { frozenCopy } from "./readonly-value.js";
3
4
  import { normalizeScalarFieldValue } from "./scalar-runtime.js";
4
5
  function isRecord(value) {
5
6
  return value !== null && typeof value === "object" && !Array.isArray(value);
6
7
  }
7
- function readBehavior(value) {
8
+ function readCompute(value) {
8
9
  if (typeof value === "function") {
9
10
  return { compute: value, dependsOn: [] };
10
11
  }
11
- if (value === undefined ||
12
- value === false ||
13
- typeof value.compute !== "function") {
12
+ if (value === undefined || typeof value.compute !== "function") {
14
13
  return undefined;
15
14
  }
16
15
  return {
@@ -18,6 +17,16 @@ function readBehavior(value) {
18
17
  dependsOn: value.dependsOn ?? [],
19
18
  };
20
19
  }
20
+ function storedScalar(model, resource, field) {
21
+ const resources = model.resources;
22
+ const fields = Object.hasOwn(resources, resource)
23
+ ? resources[resource]?.fields
24
+ : undefined;
25
+ const entry = fields !== undefined && Object.hasOwn(fields, field)
26
+ ? fields[field]
27
+ : undefined;
28
+ return isRecord(entry) && entry.kind === "scalar";
29
+ }
21
30
  function appendUnique(values, value) {
22
31
  if (!values.includes(value)) {
23
32
  values.push(value);
@@ -28,24 +37,34 @@ function appendUniqueProjection(values, value) {
28
37
  values.push(value);
29
38
  }
30
39
  }
40
+ function adapterIdentifier(model, resource) {
41
+ const resources = model.resources;
42
+ return ((Object.hasOwn(resources, resource)
43
+ ? resources[resource]?.identifiers?.[0]
44
+ : undefined) ?? []);
45
+ }
31
46
  function supportsProjection(request) {
32
47
  if (request.family === "upsert") {
33
48
  return true;
34
49
  }
35
50
  return request.variant !== "count";
36
51
  }
37
- function addScalarProjection(core, active, behaviors, resourceName, fieldName, adapterSelect, requested, computed) {
52
+ function addScalarProjection(core, model, active, compute, resourceName, fieldName, adapterSelect, requested, computed) {
38
53
  const activeField = lookupField(lookupResource(active, resourceName), fieldName);
39
54
  if (activeField?.kind !== "scalar") {
40
55
  return;
41
56
  }
42
57
  appendUnique(requested, fieldName);
43
- const behavior = readBehavior(behaviors?.[resourceName]?.fields[fieldName]?.read);
44
- if (behavior !== undefined) {
58
+ const stage = readCompute(compute?.[resourceName]?.[fieldName]?.read);
59
+ if (stage !== undefined) {
45
60
  appendUnique(computed, fieldName);
46
- for (const dependency of behavior.dependsOn) {
47
- const dependencyField = lookupField(lookupResource(core, resourceName), dependency);
48
- if (dependencyField?.kind === "scalar") {
61
+ if (stage.dependsOn.length === 0) {
62
+ for (const member of adapterIdentifier(model, resourceName)) {
63
+ appendUniqueProjection(adapterSelect, member);
64
+ }
65
+ }
66
+ for (const dependency of stage.dependsOn) {
67
+ if (storedScalar(model, resourceName, dependency)) {
49
68
  appendUniqueProjection(adapterSelect, dependency);
50
69
  }
51
70
  }
@@ -70,7 +89,7 @@ function projectionEntry(entry) {
70
89
  function withoutProjectionChoice(value) {
71
90
  return Object.fromEntries(Object.entries(value).filter(([key]) => key !== "select" && key !== "include"));
72
91
  }
73
- function defaultProjectionLevel(core, active, behaviors, resourceName) {
92
+ function defaultProjectionLevel(core, model, active, compute, resourceName) {
74
93
  const activeResource = lookupResource(active, resourceName);
75
94
  const adapterSelect = [];
76
95
  const requested = [];
@@ -80,7 +99,7 @@ function defaultProjectionLevel(core, active, behaviors, resourceName) {
80
99
  if (field.kind !== "scalar" || field.capabilities.select !== true) {
81
100
  continue;
82
101
  }
83
- addScalarProjection(core, active, behaviors, resourceName, fieldName, adapterSelect, requested, computed);
102
+ addScalarProjection(core, model, active, compute, resourceName, fieldName, adapterSelect, requested, computed);
84
103
  }
85
104
  }
86
105
  return {
@@ -94,25 +113,25 @@ function defaultProjectionLevel(core, active, behaviors, resourceName) {
94
113
  },
95
114
  };
96
115
  }
97
- function planRelationProjection(core, active, behaviors, field, value) {
116
+ function planRelationProjection(core, model, active, compute, field, value) {
98
117
  if (!isRecord(value)) {
99
- return defaultProjectionLevel(core, active, behaviors, field.target);
118
+ return defaultProjectionLevel(core, model, active, compute, field.target);
100
119
  }
101
120
  if (Array.isArray(value.select)) {
102
- return planSelectLevel(core, active, behaviors, field.target, value.select, true);
121
+ return planSelectLevel(core, model, active, compute, field.target, value.select, true);
103
122
  }
104
123
  if (Array.isArray(value.include)) {
105
- return planIncludeLevel(core, active, behaviors, field.target, value.include);
124
+ return planIncludeLevel(core, model, active, compute, field.target, value.include);
106
125
  }
107
- return defaultProjectionLevel(core, active, behaviors, field.target);
126
+ return defaultProjectionLevel(core, model, active, compute, field.target);
108
127
  }
109
- function planRelationEntry(core, active, behaviors, resourceName, fieldName, value) {
128
+ function planRelationEntry(core, model, active, compute, resourceName, fieldName, value) {
110
129
  const activeField = lookupField(lookupResource(active, resourceName), fieldName);
111
130
  const coreField = lookupField(lookupResource(core, resourceName), fieldName);
112
131
  if (activeField?.kind !== "relation" || coreField?.kind !== "relation") {
113
132
  return undefined;
114
133
  }
115
- const nested = planRelationProjection(core, active, behaviors, coreField, value);
134
+ const nested = planRelationProjection(core, model, active, compute, coreField, value);
116
135
  return {
117
136
  adapterEntry: {
118
137
  [fieldName]: {
@@ -127,7 +146,7 @@ function planRelationEntry(core, active, behaviors, resourceName, fieldName, val
127
146
  },
128
147
  };
129
148
  }
130
- function planSelectLevel(core, active, behaviors, resourceName, select, collectReducers = false) {
149
+ function planSelectLevel(core, model, active, compute, resourceName, select, collectReducers = false) {
131
150
  const activeResource = lookupResource(active, resourceName);
132
151
  const coreResource = lookupResource(core, resourceName);
133
152
  const adapterSelect = [];
@@ -159,11 +178,11 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
159
178
  const activeField = lookupField(activeResource, entry);
160
179
  const coreField = lookupField(coreResource, entry);
161
180
  if (activeField?.kind === "scalar") {
162
- addScalarProjection(core, active, behaviors, resourceName, entry, adapterSelect, requested, computed);
181
+ addScalarProjection(core, model, active, compute, resourceName, entry, adapterSelect, requested, computed);
163
182
  continue;
164
183
  }
165
184
  if (activeField?.kind === "relation" && coreField?.kind === "relation") {
166
- const plannedRelation = planRelationEntry(core, active, behaviors, resourceName, entry, undefined);
185
+ const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, entry, undefined);
167
186
  if (plannedRelation !== undefined) {
168
187
  appendUnique(requested, entry);
169
188
  adapterSelect.push(plannedRelation.adapterEntry);
@@ -180,7 +199,7 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
180
199
  continue;
181
200
  }
182
201
  const [fieldName, nestedValue] = relationEntry;
183
- const plannedRelation = planRelationEntry(core, active, behaviors, resourceName, fieldName, nestedValue);
202
+ const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, fieldName, nestedValue);
184
203
  if (plannedRelation === undefined) {
185
204
  adapterSelect.push(entry);
186
205
  continue;
@@ -194,15 +213,15 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
194
213
  plan: { resource: resourceName, requested, computed, relations, reducers },
195
214
  };
196
215
  }
197
- function planIncludeLevel(core, active, behaviors, resourceName, include) {
198
- const defaults = defaultProjectionLevel(core, active, behaviors, resourceName);
216
+ function planIncludeLevel(core, model, active, compute, resourceName, include) {
217
+ const defaults = defaultProjectionLevel(core, model, active, compute, resourceName);
199
218
  const adapterSelect = [...defaults.select];
200
219
  const requested = [...defaults.plan.requested];
201
220
  const computed = [...defaults.plan.computed];
202
221
  const relations = [];
203
222
  for (const entry of include) {
204
223
  if (typeof entry === "string") {
205
- const plannedRelation = planRelationEntry(core, active, behaviors, resourceName, entry, undefined);
224
+ const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, entry, undefined);
206
225
  if (plannedRelation === undefined) {
207
226
  continue;
208
227
  }
@@ -216,7 +235,7 @@ function planIncludeLevel(core, active, behaviors, resourceName, include) {
216
235
  continue;
217
236
  }
218
237
  const [fieldName, nestedValue] = relationEntry;
219
- const plannedRelation = planRelationEntry(core, active, behaviors, resourceName, fieldName, nestedValue);
238
+ const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, fieldName, nestedValue);
220
239
  if (plannedRelation === undefined) {
221
240
  continue;
222
241
  }
@@ -241,7 +260,7 @@ function replaceWithInternalSelect(args, select) {
241
260
  internal.select = select;
242
261
  return internal;
243
262
  }
244
- export function planReadOperation(core, active, behaviors, request, args) {
263
+ export function planReadOperation(core, model, active, compute, request, args) {
245
264
  if (!isRecord(args) || !supportsProjection(request)) {
246
265
  return { arguments: args, projection: undefined, materialize: false };
247
266
  }
@@ -251,7 +270,7 @@ export function planReadOperation(core, active, behaviors, request, args) {
251
270
  return { arguments: args, projection: undefined, materialize: false };
252
271
  }
253
272
  if (Array.isArray(args.select)) {
254
- const planned = planSelectLevel(core, active, behaviors, request.resource, args.select);
273
+ const planned = planSelectLevel(core, model, active, compute, request.resource, args.select);
255
274
  return {
256
275
  arguments: replaceWithInternalSelect(args, planned.select),
257
276
  projection: planned.plan,
@@ -259,21 +278,21 @@ export function planReadOperation(core, active, behaviors, request, args) {
259
278
  };
260
279
  }
261
280
  if (Array.isArray(args.include)) {
262
- const planned = planIncludeLevel(core, active, behaviors, request.resource, args.include);
281
+ const planned = planIncludeLevel(core, model, active, compute, request.resource, args.include);
263
282
  return {
264
283
  arguments: replaceWithInternalSelect(args, planned.select),
265
284
  projection: planned.plan,
266
285
  materialize: true,
267
286
  };
268
287
  }
269
- const defaults = defaultProjectionLevel(core, active, behaviors, request.resource);
288
+ const defaults = defaultProjectionLevel(core, model, active, compute, request.resource);
270
289
  return {
271
290
  arguments: { ...args, select: defaults.select },
272
291
  projection: defaults.plan,
273
292
  materialize: defaults.plan.computed.length > 0,
274
293
  };
275
294
  }
276
- async function materializeRelation(active, behaviors, request, relation, value, contextFactory) {
295
+ async function materializeRelation(active, compute, request, relation, value, contextFactory) {
277
296
  if (value === null || value === undefined) {
278
297
  return value;
279
298
  }
@@ -281,11 +300,11 @@ async function materializeRelation(active, behaviors, request, relation, value,
281
300
  if (!Array.isArray(value)) {
282
301
  return value;
283
302
  }
284
- return Promise.all(value.map((entry) => materializeRecord(active, behaviors, request, relation.projection, entry, contextFactory)));
303
+ return Promise.all(value.map((entry) => materializeRecord(active, compute, request, relation.projection, entry, contextFactory)));
285
304
  }
286
- return materializeRecord(active, behaviors, request, relation.projection, value, contextFactory);
305
+ return materializeRecord(active, compute, request, relation.projection, value, contextFactory);
287
306
  }
288
- async function materializeRecord(active, behaviors, request, plan, value, contextFactory) {
307
+ async function materializeRecord(active, compute, request, plan, value, contextFactory) {
289
308
  if (!isRecord(value)) {
290
309
  return value;
291
310
  }
@@ -296,24 +315,31 @@ async function materializeRecord(active, behaviors, request, plan, value, contex
296
315
  const record = { ...value };
297
316
  for (const fieldName of plan.computed) {
298
317
  const field = lookupField(resource, fieldName);
299
- const behavior = readBehavior(behaviors?.[plan.resource]?.fields[fieldName]?.read);
300
- if (field?.kind !== "scalar" || behavior === undefined) {
318
+ const stage = readCompute(compute?.[plan.resource]?.[fieldName]?.read);
319
+ if (field?.kind !== "scalar" || stage === undefined) {
301
320
  continue;
302
321
  }
303
- const computedValue = await behavior.compute({
304
- origin: request.origin,
305
- resource: plan.resource,
322
+ const view = frozenCopy(record);
323
+ const computedValue = await stage.compute({
306
324
  field: fieldName,
307
- value: record[fieldName],
308
- record,
309
- operation: contextFactory(),
325
+ value: view[fieldName],
326
+ record: view,
327
+ ctx: contextFactory(),
310
328
  });
311
329
  if (computedValue === undefined) {
312
330
  continue;
313
331
  }
314
- const validation = normalizeScalarFieldValue(active, field, computedValue, "runtime", ["behaviors", plan.resource, fieldName, "read"]);
332
+ const validation = normalizeScalarFieldValue(active, field, computedValue, "runtime", [
333
+ "resources",
334
+ plan.resource,
335
+ "fields",
336
+ fieldName,
337
+ "pipelines",
338
+ "compute",
339
+ "read",
340
+ ]);
315
341
  if (!validation.ok) {
316
- throw new ComputedValueError(plan.resource, fieldName, "read", validation.issues);
342
+ throw new AvComputedValueError(plan.resource, fieldName, "read", validation.issues);
317
343
  }
318
344
  record[fieldName] = validation.value;
319
345
  }
@@ -321,19 +347,19 @@ async function materializeRecord(active, behaviors, request, plan, value, contex
321
347
  if (!Object.hasOwn(record, relation.field)) {
322
348
  continue;
323
349
  }
324
- record[relation.field] = await materializeRelation(active, behaviors, request, relation, record[relation.field], contextFactory);
350
+ record[relation.field] = await materializeRelation(active, compute, request, relation, record[relation.field], contextFactory);
325
351
  }
326
352
  return Object.fromEntries(plan.requested
327
353
  .filter((fieldName) => Object.hasOwn(record, fieldName))
328
354
  .map((fieldName) => [fieldName, record[fieldName]]));
329
355
  }
330
- export async function materializeReadOperation(active, behaviors, request, plan, value, contextFactory) {
356
+ export async function materializeReadOperation(active, compute, request, plan, value, contextFactory) {
331
357
  const projection = plan.projection;
332
358
  if (!plan.materialize || projection === undefined) {
333
359
  return value;
334
360
  }
335
361
  if (Array.isArray(value)) {
336
- return Promise.all(value.map((entry) => materializeRecord(active, behaviors, request, projection, entry, contextFactory)));
362
+ return Promise.all(value.map((entry) => materializeRecord(active, compute, request, projection, entry, contextFactory)));
337
363
  }
338
- return materializeRecord(active, behaviors, request, projection, value, contextFactory);
364
+ return materializeRecord(active, compute, request, projection, value, contextFactory);
339
365
  }
@@ -1,13 +1,14 @@
1
- import type { ValidationIssue } from "../operations/validation-code.js";
1
+ import type { AvValidationIssue } from "../operations/validation-code.js";
2
2
  /**
3
3
  * What the diagnostics channel receives when a computed value — a read or write
4
- * behavior's return — is one its Contract refuses: the developer's broken code,
4
+ * compute stage's return — is one its Contract refuses, or a `compute.create`
5
+ * stage returned `undefined` for a field a create cannot do without (rc.2): the developer's broken code,
5
6
  * never the caller's. It is thrown, not a deliberate outcome, so the framework's
6
7
  * boundary answers the caller the generic `A3000` and reports this error, with the
7
8
  * issues, exactly once.
8
9
  */
9
- export declare class ComputedValueError extends Error {
10
- readonly issues: readonly ValidationIssue[];
11
- readonly name = "ComputedValueError";
12
- constructor(resource: string, field: string, stage: "read" | "create" | "update", issues: readonly ValidationIssue[]);
10
+ export declare class AvComputedValueError extends Error {
11
+ readonly issues: readonly AvValidationIssue[];
12
+ readonly name = "AvComputedValueError";
13
+ constructor(resource: string, field: string, stage: "read" | "create" | "update", issues: readonly AvValidationIssue[], message?: string);
13
14
  }
@@ -1,9 +1,10 @@
1
- export class ComputedValueError extends Error {
1
+ export class AvComputedValueError extends Error {
2
2
  issues;
3
- name = "ComputedValueError";
4
- constructor(resource, field, stage, issues) {
3
+ name = "AvComputedValueError";
4
+ constructor(resource, field, stage, issues, message) {
5
5
  const [first] = issues;
6
- super(`The ${stage} behavior of ${resource}.${field} returned a value its Contract refuses${first === undefined ? "." : ` (${first.code}: ${first.message})`}`);
6
+ super(message ??
7
+ `The compute.${stage} stage of ${resource}.${field} returned a value its Contract refuses${first === undefined ? "." : ` (${first.code}: ${first.message})`}`);
7
8
  this.issues = issues;
8
9
  }
9
10
  }
@@ -0,0 +1,59 @@
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 { AvRequestOrigin } from "../config/config-layer.js";
5
+ import type { AvContract } from "../contracts/contract.js";
6
+ import type { AvOperationFamily } from "../operations/operation-identity.js";
7
+ import { type AvDiagnosticsSink } from "./diagnostics-reporter.js";
8
+ import type { AvComputeContext } from "./field-compute.js";
9
+ import type { MisuseReporter } from "./misuse-reporter.js";
10
+ import type { ApplicationOperationRequest } from "./operation-request.js";
11
+ import type { AvOperationResponse } from "./operation-response.js";
12
+ import type { AvContext, AvTransactionContext, AvTransportContext } from "./pipeline.js";
13
+ import type { AvState } from "./request-state.js";
14
+ /** Where a ctx's calls run: inside the open transaction, or standalone. */
15
+ export type ExecutorScope<M extends AvAdapterModel = AvAdapterModel> = {
16
+ /** The request id every call of this ctx carries: its stage's request's. */
17
+ readonly requestId: string;
18
+ /** The open transaction's executor; `undefined` outside any transaction. */
19
+ readonly transaction: AvAdapterTransactionExecutor<M> | undefined;
20
+ /** The request's state, which every call of this ctx inherits. */
21
+ readonly state: AvState;
22
+ };
23
+ /** The `$` facts a ctx states, as own data properties. */
24
+ export type ContextFacts = {
25
+ readonly $origin: AvRequestOrigin;
26
+ readonly $requestId: string;
27
+ readonly $transport?: AvTransportContext;
28
+ readonly $contract: AvContract;
29
+ readonly $operation?: {
30
+ readonly resource: string;
31
+ readonly family: AvOperationFamily;
32
+ readonly variant: string;
33
+ readonly nested?: true;
34
+ };
35
+ readonly $args: unknown;
36
+ };
37
+ /** Runs one raw application-origin call in `transaction`, or standalone. Total. */
38
+ export type RawOperationRunner<M extends AvAdapterModel> = (request: ApplicationOperationRequest, transaction: AvAdapterTransactionExecutor<M> | undefined) => Promise<AvOperationResponse>;
39
+ export type ContextExecutorDependencies<M extends AvAdapterModel> = {
40
+ /** The model, as construction read it once: the ctx's Resources. */
41
+ readonly model: M;
42
+ readonly adapter: AvAdapter<M>;
43
+ /** The Application Contract: a `ctx.$transaction` needs its transactions. */
44
+ readonly application: AvContract;
45
+ readonly diagnostics: AvDiagnosticsSink | undefined;
46
+ readonly misuse: MisuseReporter;
47
+ readonly run: RawOperationRunner<M>;
48
+ };
49
+ /** Builds the ctx every stage is told. */
50
+ export type ContextExecutor<M extends AvAdapterModel = AvAdapterModel> = {
51
+ /** An operation stage's ctx: its facts and the full executor. */
52
+ readonly operation: (scope: ExecutorScope<M>, facts: ContextFacts) => AvContext;
53
+ /** A Resource transaction stage's ctx: the plan as `$args`, the full executor. */
54
+ readonly transaction: (scope: ExecutorScope<M>, facts: ContextFacts) => AvTransactionContext;
55
+ /** Compute's read-only ctx: the facts, and `find.*` reads only. */
56
+ readonly compute: (scope: ExecutorScope<M>, facts: ContextFacts) => AvComputeContext;
57
+ };
58
+ /** Builds the ctx factory of one Framework over its model. */
59
+ export declare function createContextExecutor<M extends AvAdapterModel>(dependencies: ContextExecutorDependencies<M>): ContextExecutor<M>;