@getodk/xforms-engine 0.4.0 → 0.5.0

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 (285) hide show
  1. package/dist/client/BaseNode.d.ts +14 -3
  2. package/dist/client/BaseValueNode.d.ts +32 -0
  3. package/dist/client/EngineConfig.d.ts +49 -48
  4. package/dist/client/InputNode.d.ts +53 -0
  5. package/dist/client/ModelValueNode.d.ts +12 -7
  6. package/dist/client/NoteNode.d.ts +2 -2
  7. package/dist/client/RootNode.d.ts +34 -7
  8. package/dist/client/SelectNode.d.ts +2 -2
  9. package/dist/client/ValueType.d.ts +3 -0
  10. package/dist/client/constants.d.ts +50 -0
  11. package/dist/client/hierarchy.d.ts +4 -4
  12. package/dist/client/identity.d.ts +14 -0
  13. package/dist/client/node-types.d.ts +2 -1
  14. package/dist/client/resources.d.ts +93 -0
  15. package/dist/client/submission/SubmissionData.d.ts +7 -0
  16. package/dist/client/submission/SubmissionDefinition.d.ts +14 -0
  17. package/dist/client/submission/SubmissionInstanceFile.d.ts +6 -0
  18. package/dist/client/submission/SubmissionOptions.d.ts +23 -0
  19. package/dist/client/submission/SubmissionResult.d.ts +91 -0
  20. package/dist/client/submission/SubmissionState.d.ts +12 -0
  21. package/dist/client/validation.d.ts +2 -2
  22. package/dist/error/ErrorProductionDesignPendingError.d.ts +7 -0
  23. package/dist/error/ValueTypeInvariantError.d.ts +17 -0
  24. package/dist/error/XPathFunctionalityError.d.ts +14 -0
  25. package/dist/error/XPathFunctionalityNotSupportedError.d.ts +7 -0
  26. package/dist/error/XPathFunctionalityPendingError.d.ts +7 -0
  27. package/dist/index.d.ts +10 -1
  28. package/dist/index.js +10856 -8585
  29. package/dist/index.js.map +1 -1
  30. package/dist/instance/Group.d.ts +9 -4
  31. package/dist/instance/InputControl.d.ts +36 -0
  32. package/dist/instance/ModelValue.d.ts +16 -26
  33. package/dist/instance/Note.d.ts +10 -3
  34. package/dist/instance/PrimaryInstance.d.ts +84 -0
  35. package/dist/instance/Root.d.ts +29 -25
  36. package/dist/instance/SelectField.d.ts +10 -2
  37. package/dist/instance/Subtree.d.ts +10 -5
  38. package/dist/instance/TriggerControl.d.ts +10 -3
  39. package/dist/instance/abstract/DescendantNode.d.ts +31 -23
  40. package/dist/instance/abstract/InstanceNode.d.ts +49 -29
  41. package/dist/instance/abstract/UnsupportedControl.d.ts +10 -3
  42. package/dist/instance/abstract/ValueNode.d.ts +48 -0
  43. package/dist/instance/hierarchy.d.ts +9 -8
  44. package/dist/instance/identity.d.ts +2 -7
  45. package/dist/instance/internal-api/EvaluationContext.d.ts +53 -12
  46. package/dist/instance/internal-api/InstanceConfig.d.ts +8 -2
  47. package/dist/instance/internal-api/InstanceValueContext.d.ts +20 -0
  48. package/dist/instance/internal-api/PrimaryInstanceDocument.d.ts +36 -0
  49. package/dist/instance/internal-api/TranslationContext.d.ts +3 -2
  50. package/dist/instance/internal-api/ValidationContext.d.ts +3 -4
  51. package/dist/instance/internal-api/ValueContext.d.ts +2 -1
  52. package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +14 -0
  53. package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +31 -0
  54. package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +18 -0
  55. package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +17 -0
  56. package/dist/instance/repeat/BaseRepeatRange.d.ts +39 -83
  57. package/dist/instance/repeat/RepeatInstance.d.ts +11 -29
  58. package/dist/instance/repeat/RepeatRangeControlled.d.ts +2 -2
  59. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +2 -2
  60. package/dist/instance/resource.d.ts +1 -1
  61. package/dist/instance/text/TextRange.d.ts +1 -1
  62. package/dist/instance/unsupported/RangeControl.d.ts +3 -1
  63. package/dist/instance/unsupported/RankControl.d.ts +3 -1
  64. package/dist/instance/unsupported/UploadControl.d.ts +3 -1
  65. package/dist/integration/xpath/EngineXPathEvaluator.d.ts +14 -0
  66. package/dist/integration/xpath/adapter/XFormsXPathNode.d.ts +71 -0
  67. package/dist/integration/xpath/adapter/engineDOMAdapter.d.ts +5 -0
  68. package/dist/integration/xpath/adapter/kind.d.ts +32 -0
  69. package/dist/integration/xpath/adapter/names.d.ts +16 -0
  70. package/dist/integration/xpath/adapter/traversal.d.ts +25 -0
  71. package/dist/integration/xpath/adapter/values.d.ts +2 -0
  72. package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +19 -0
  73. package/dist/integration/xpath/static-dom/StaticDocument.d.ts +16 -0
  74. package/dist/integration/xpath/static-dom/StaticElement.d.ts +40 -0
  75. package/dist/integration/xpath/static-dom/StaticNamedNode.d.ts +17 -0
  76. package/dist/integration/xpath/static-dom/StaticNode.d.ts +33 -0
  77. package/dist/integration/xpath/static-dom/StaticText.d.ts +16 -0
  78. package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +3 -0
  79. package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +3 -0
  80. package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +4 -0
  81. package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +4 -0
  82. package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +3 -0
  83. package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +8 -0
  84. package/dist/lib/codecs/DecimalValueCodec.d.ts +6 -0
  85. package/dist/lib/codecs/IntValueCodec.d.ts +6 -0
  86. package/dist/lib/codecs/StringValueCodec.d.ts +4 -0
  87. package/dist/lib/codecs/ValueCodec.d.ts +30 -0
  88. package/dist/lib/codecs/ValueTypePlaceholderCodec.d.ts +12 -0
  89. package/dist/lib/codecs/getSharedValueCodec.d.ts +47 -0
  90. package/dist/lib/dom/query.d.ts +3 -0
  91. package/dist/lib/reactivity/createChildrenState.d.ts +7 -5
  92. package/dist/lib/reactivity/createComputedExpression.d.ts +18 -5
  93. package/dist/lib/reactivity/createInstanceValueState.d.ts +40 -0
  94. package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +2 -2
  95. package/dist/lib/reactivity/createTranslationState.d.ts +19 -0
  96. package/dist/lib/reactivity/createValueState.d.ts +6 -10
  97. package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +4 -4
  98. package/dist/lib/xml-serialization.d.ts +41 -0
  99. package/dist/parse/XFormDOM.d.ts +18 -7
  100. package/dist/parse/XFormDefinition.d.ts +1 -2
  101. package/dist/parse/attachments/FormAttachmentResource.d.ts +27 -0
  102. package/dist/parse/body/BodyDefinition.d.ts +3 -3
  103. package/dist/parse/body/RepeatElementDefinition.d.ts +1 -1
  104. package/dist/parse/body/appearance/inputAppearanceParser.d.ts +1 -1
  105. package/dist/parse/body/control/{InputDefinition.d.ts → InputControlDefinition.d.ts} +1 -1
  106. package/dist/parse/body/control/select/ItemsetNodesetContext.d.ts +0 -2
  107. package/dist/parse/expression/abstract/DependencyContext.d.ts +0 -5
  108. package/dist/parse/expression/abstract/DependentExpression.d.ts +2 -3
  109. package/dist/parse/model/BindDefinition.d.ts +4 -5
  110. package/dist/parse/model/BindTypeDefinition.d.ts +20 -0
  111. package/dist/parse/model/DescendentNodeDefinition.d.ts +0 -1
  112. package/dist/parse/model/FormSubmissionDefinition.d.ts +8 -0
  113. package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +4 -0
  114. package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +8 -0
  115. package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +8 -0
  116. package/dist/parse/model/LeafNodeDefinition.d.ts +3 -1
  117. package/dist/parse/model/ModelBindMap.d.ts +1 -1
  118. package/dist/parse/model/ModelDefinition.d.ts +2 -0
  119. package/dist/parse/model/NodeDefinition.d.ts +0 -1
  120. package/dist/parse/model/NoteNodeDefinition.d.ts +4 -4
  121. package/dist/parse/model/RootDefinition.d.ts +3 -2
  122. package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +4 -0
  123. package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +7 -0
  124. package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +13 -0
  125. package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +14 -0
  126. package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +22 -0
  127. package/dist/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.d.ts +23 -0
  128. package/dist/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceSource.d.ts +9 -0
  129. package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +5 -0
  130. package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +7 -0
  131. package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +13 -0
  132. package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +12 -0
  133. package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +24 -0
  134. package/dist/parse/text/abstract/TextRangeDefinition.d.ts +0 -2
  135. package/dist/parse/xpath/semantic-analysis.d.ts +5 -0
  136. package/dist/solid.js +8174 -5921
  137. package/dist/solid.js.map +1 -1
  138. package/package.json +13 -11
  139. package/src/client/BaseNode.ts +16 -6
  140. package/src/client/BaseValueNode.ts +35 -0
  141. package/src/client/EngineConfig.ts +52 -51
  142. package/src/client/InputNode.ts +77 -0
  143. package/src/client/ModelValueNode.ts +30 -7
  144. package/src/client/NoteNode.ts +2 -2
  145. package/src/client/RootNode.ts +37 -7
  146. package/src/client/SelectNode.ts +3 -3
  147. package/src/client/ValueType.ts +4 -0
  148. package/src/client/constants.ts +67 -0
  149. package/src/client/hierarchy.ts +5 -5
  150. package/src/client/identity.ts +16 -0
  151. package/src/client/node-types.ts +12 -6
  152. package/src/client/resources.ts +118 -0
  153. package/src/client/submission/SubmissionData.ts +12 -0
  154. package/src/client/submission/SubmissionDefinition.ts +16 -0
  155. package/src/client/submission/SubmissionInstanceFile.ts +9 -0
  156. package/src/client/submission/SubmissionOptions.ts +28 -0
  157. package/src/client/submission/SubmissionResult.ts +124 -0
  158. package/src/client/submission/SubmissionState.ts +14 -0
  159. package/src/client/validation.ts +2 -2
  160. package/src/error/ErrorProductionDesignPendingError.ts +6 -0
  161. package/src/error/ValueTypeInvariantError.ts +22 -0
  162. package/src/error/XPathFunctionalityError.ts +26 -0
  163. package/src/error/XPathFunctionalityNotSupportedError.ts +18 -0
  164. package/src/error/XPathFunctionalityPendingError.ts +18 -0
  165. package/src/index.ts +10 -1
  166. package/src/instance/Group.ts +17 -5
  167. package/src/instance/InputControl.ts +119 -0
  168. package/src/instance/ModelValue.ts +47 -54
  169. package/src/instance/Note.ts +24 -8
  170. package/src/instance/PrimaryInstance.ts +244 -0
  171. package/src/instance/Root.ts +62 -134
  172. package/src/instance/SelectField.ts +56 -19
  173. package/src/instance/Subtree.ts +19 -7
  174. package/src/instance/TriggerControl.ts +23 -6
  175. package/src/instance/abstract/DescendantNode.ts +90 -45
  176. package/src/instance/abstract/InstanceNode.ts +103 -105
  177. package/src/instance/abstract/UnsupportedControl.ts +28 -5
  178. package/src/instance/abstract/ValueNode.ts +127 -0
  179. package/src/instance/children.ts +9 -10
  180. package/src/instance/hierarchy.ts +19 -15
  181. package/src/instance/identity.ts +3 -9
  182. package/src/instance/index.ts +25 -7
  183. package/src/instance/internal-api/EvaluationContext.ts +60 -13
  184. package/src/instance/internal-api/InstanceConfig.ts +9 -2
  185. package/src/instance/internal-api/InstanceValueContext.ts +24 -0
  186. package/src/instance/internal-api/PrimaryInstanceDocument.ts +53 -0
  187. package/src/instance/internal-api/TranslationContext.ts +3 -2
  188. package/src/instance/internal-api/ValidationContext.ts +3 -4
  189. package/src/instance/internal-api/ValueContext.ts +2 -1
  190. package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +20 -0
  191. package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +42 -0
  192. package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +25 -0
  193. package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +23 -0
  194. package/src/instance/repeat/BaseRepeatRange.ts +50 -131
  195. package/src/instance/repeat/RepeatInstance.ts +20 -46
  196. package/src/instance/repeat/RepeatRangeControlled.ts +5 -5
  197. package/src/instance/repeat/RepeatRangeUncontrolled.ts +2 -4
  198. package/src/instance/resource.ts +1 -1
  199. package/src/instance/text/TextChunk.ts +1 -1
  200. package/src/instance/unsupported/RangeControl.ts +5 -1
  201. package/src/instance/unsupported/RankControl.ts +5 -1
  202. package/src/instance/unsupported/UploadControl.ts +5 -1
  203. package/src/integration/xpath/EngineXPathEvaluator.ts +22 -0
  204. package/src/integration/xpath/adapter/XFormsXPathNode.ts +126 -0
  205. package/src/integration/xpath/adapter/engineDOMAdapter.ts +57 -0
  206. package/src/integration/xpath/adapter/kind.ts +114 -0
  207. package/src/integration/xpath/adapter/names.ts +99 -0
  208. package/src/integration/xpath/adapter/traversal.ts +228 -0
  209. package/src/integration/xpath/adapter/values.ts +5 -0
  210. package/src/integration/xpath/static-dom/StaticAttribute.ts +33 -0
  211. package/src/integration/xpath/static-dom/StaticDocument.ts +38 -0
  212. package/src/integration/xpath/static-dom/StaticElement.ts +106 -0
  213. package/src/integration/xpath/static-dom/StaticNamedNode.ts +45 -0
  214. package/src/integration/xpath/static-dom/StaticNode.ts +68 -0
  215. package/src/integration/xpath/static-dom/StaticText.ts +28 -0
  216. package/src/lib/client-reactivity/README.md +0 -0
  217. package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +12 -0
  218. package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +20 -0
  219. package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +17 -0
  220. package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +22 -0
  221. package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +21 -0
  222. package/src/lib/client-reactivity/submission/prepareSubmission.ts +172 -0
  223. package/src/lib/codecs/DecimalValueCodec.ts +46 -0
  224. package/src/lib/codecs/IntValueCodec.ts +100 -0
  225. package/src/lib/codecs/StringValueCodec.ts +11 -0
  226. package/src/lib/codecs/ValueCodec.ts +106 -0
  227. package/src/lib/codecs/ValueTypePlaceholderCodec.ts +19 -0
  228. package/src/lib/codecs/getSharedValueCodec.ts +77 -0
  229. package/src/lib/dom/query.ts +7 -0
  230. package/src/lib/reactivity/createChildrenState.ts +8 -6
  231. package/src/lib/reactivity/createComputedExpression.ts +57 -34
  232. package/src/lib/reactivity/createInstanceValueState.ts +166 -0
  233. package/src/lib/reactivity/createNoteReadonlyThunk.ts +12 -7
  234. package/src/lib/reactivity/createSelectItems.ts +21 -21
  235. package/src/lib/reactivity/createTranslationState.ts +61 -0
  236. package/src/lib/reactivity/createValueState.ts +62 -120
  237. package/src/lib/reactivity/materializeCurrentStateChildren.ts +7 -7
  238. package/src/lib/reactivity/text/createTextRange.ts +4 -3
  239. package/src/lib/reactivity/validation/createAggregatedViolations.ts +1 -1
  240. package/src/lib/reactivity/validation/createValidation.ts +2 -3
  241. package/src/lib/xml-serialization.ts +96 -0
  242. package/src/parse/XFormDOM.ts +110 -75
  243. package/src/parse/XFormDefinition.ts +1 -6
  244. package/src/parse/attachments/FormAttachmentResource.ts +40 -0
  245. package/src/parse/body/BodyDefinition.ts +3 -3
  246. package/src/parse/body/appearance/inputAppearanceParser.ts +1 -1
  247. package/src/parse/body/control/{InputDefinition.ts → InputControlDefinition.ts} +3 -5
  248. package/src/parse/body/control/select/ItemsetNodesetContext.ts +0 -5
  249. package/src/parse/expression/abstract/DependencyContext.ts +0 -26
  250. package/src/parse/expression/abstract/DependentExpression.ts +2 -13
  251. package/src/parse/model/BindDefinition.ts +5 -8
  252. package/src/parse/model/BindTypeDefinition.ts +175 -0
  253. package/src/parse/model/DescendentNodeDefinition.ts +0 -6
  254. package/src/parse/model/FormSubmissionDefinition.ts +44 -0
  255. package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +4 -0
  256. package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +41 -0
  257. package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +31 -0
  258. package/src/parse/model/LeafNodeDefinition.ts +4 -1
  259. package/src/parse/model/ModelBindMap.ts +6 -8
  260. package/src/parse/model/ModelDefinition.ts +6 -1
  261. package/src/parse/model/NodeDefinition.ts +0 -3
  262. package/src/parse/model/NoteNodeDefinition.ts +3 -3
  263. package/src/parse/model/RootDefinition.ts +2 -1
  264. package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +4 -0
  265. package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +12 -0
  266. package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +102 -0
  267. package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +40 -0
  268. package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +288 -0
  269. package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.ts +222 -0
  270. package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceSource.ts +22 -0
  271. package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +414 -0
  272. package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +19 -0
  273. package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +29 -0
  274. package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +32 -0
  275. package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +149 -0
  276. package/src/parse/text/abstract/TextRangeDefinition.ts +0 -6
  277. package/src/parse/xpath/semantic-analysis.ts +29 -0
  278. package/dist/client/StringNode.d.ts +0 -46
  279. package/dist/instance/StringField.d.ts +0 -44
  280. package/dist/instance/internal-api/SubscribableDependency.d.ts +0 -59
  281. package/dist/parse/XFormDataType.d.ts +0 -25
  282. package/src/client/StringNode.ts +0 -52
  283. package/src/instance/StringField.ts +0 -120
  284. package/src/instance/internal-api/SubscribableDependency.ts +0 -61
  285. package/src/parse/XFormDataType.ts +0 -62
@@ -0,0 +1,42 @@
1
+ import type { SubmissionState } from '../../../client/submission/SubmissionState.ts';
2
+ import type { EscapedXMLText } from '../../../lib/xml-serialization.ts';
3
+ import type {
4
+ ClientReactiveSubmittableChildNode,
5
+ ClientReactiveSubmittableParentNode,
6
+ } from './ClientReactiveSubmittableParentNode.ts';
7
+
8
+ interface ClientReactiveSubmittableLeafNodeCurrentState<RuntimeValue> {
9
+ get relevant(): boolean;
10
+ get value(): RuntimeValue;
11
+ }
12
+
13
+ export type SerializedSubmissionValue = string;
14
+
15
+ interface ClientReactiveSubmittableLeafNodeDefinition {
16
+ readonly nodeName: string;
17
+ }
18
+
19
+ export interface ClientReactiveSubmittableLeafNode<RuntimeValue> {
20
+ readonly definition: ClientReactiveSubmittableLeafNodeDefinition;
21
+ readonly parent: ClientReactiveSubmittableParentNode<ClientReactiveSubmittableChildNode>;
22
+ readonly currentState: ClientReactiveSubmittableLeafNodeCurrentState<RuntimeValue>;
23
+
24
+ /**
25
+ * A client-reactive submittable leaf node is responsible for producing a
26
+ * string representation of its value state, suitable for serialization for
27
+ * submission. It **MUST NOT** perform any further submission-specific
28
+ * serialization duties: in particular, the value **MUST NOT** be escaped for
29
+ * XML. This responsibility is delegated up the stack, to avoid repeat
30
+ * escaping.
31
+ *
32
+ * Note: excluding {@link EscapedXMLText} here does not have an effect on the
33
+ * type system, it is a documentation-only hint, to help guard against future
34
+ * double-escaping mistakes.
35
+ */
36
+ readonly encodeValue: (
37
+ this: unknown,
38
+ runtimeValue: RuntimeValue
39
+ ) => Exclude<string, EscapedXMLText>;
40
+
41
+ readonly submissionState: SubmissionState;
42
+ }
@@ -0,0 +1,25 @@
1
+ import type { SubmissionState } from '../../../client/submission/SubmissionState.ts';
2
+
3
+ export interface ClientReactiveSubmittableChildNode {
4
+ readonly submissionState: SubmissionState;
5
+ }
6
+
7
+ interface ClientReactiveSubmittableParentNodeCurrentState<
8
+ Child extends ClientReactiveSubmittableChildNode,
9
+ > {
10
+ get relevant(): boolean;
11
+ get children(): readonly Child[];
12
+ }
13
+
14
+ export interface ClientReactiveSubmittableParentNodeDefinition {
15
+ readonly nodeName: string;
16
+ }
17
+
18
+ export interface ClientReactiveSubmittableParentNode<
19
+ Child extends ClientReactiveSubmittableChildNode,
20
+ > {
21
+ readonly definition: ClientReactiveSubmittableParentNodeDefinition;
22
+ readonly parent: ClientReactiveSubmittableParentNode<ClientReactiveSubmittableChildNode> | null;
23
+ readonly currentState: ClientReactiveSubmittableParentNodeCurrentState<Child>;
24
+ readonly submissionState: SubmissionState;
25
+ }
@@ -0,0 +1,23 @@
1
+ import type { SubmissionState } from '../../../client/submission/SubmissionState.ts';
2
+ import type {
3
+ ClientReactiveSubmittableChildNode,
4
+ ClientReactiveSubmittableParentNode,
5
+ } from './ClientReactiveSubmittableParentNode.ts';
6
+
7
+ interface ClientReactiveSubmittableValueNodeCurrentState {
8
+ get relevant(): boolean;
9
+ get instanceValue(): string;
10
+ }
11
+
12
+ export type SerializedSubmissionValue = string;
13
+
14
+ interface ClientReactiveSubmittableValueNodeDefinition {
15
+ readonly nodeName: string;
16
+ }
17
+
18
+ export interface ClientReactiveSubmittableValueNode {
19
+ readonly definition: ClientReactiveSubmittableValueNodeDefinition;
20
+ readonly parent: ClientReactiveSubmittableParentNode<ClientReactiveSubmittableChildNode>;
21
+ readonly currentState: ClientReactiveSubmittableValueNodeCurrentState;
22
+ readonly submissionState: SubmissionState;
23
+ }
@@ -1,12 +1,22 @@
1
1
  import { insertAtIndex } from '@getodk/common/lib/array/insert.ts';
2
- import { untrack, type Accessor } from 'solid-js';
2
+ import { XPathNodeKindKey } from '@getodk/xpath';
3
+ import type { Accessor } from 'solid-js';
4
+ import { untrack } from 'solid-js';
5
+ import type { RepeatRangeNode } from '../../client/hierarchy.ts';
6
+ import type { FormNodeID } from '../../client/identity.ts';
3
7
  import type { NodeAppearances } from '../../client/NodeAppearances.ts';
4
8
  import type { BaseRepeatRangeNode } from '../../client/repeat/BaseRepeatRangeNode.ts';
9
+ import type { SubmissionState } from '../../client/submission/SubmissionState.ts';
5
10
  import type { TextRange } from '../../client/TextRange.ts';
6
11
  import type { AncestorNodeValidationState } from '../../client/validation.ts';
12
+ import type {
13
+ XFormsXPathNodeRange,
14
+ XFormsXPathNodeRangeKind,
15
+ } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
16
+ import { XFORMS_XPATH_NODE_RANGE_KIND } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
17
+ import { createNodeRangeSubmissionState } from '../../lib/client-reactivity/submission/createNodeRangeSubmissionState.ts';
7
18
  import type { ChildrenState } from '../../lib/reactivity/createChildrenState.ts';
8
19
  import { createChildrenState } from '../../lib/reactivity/createChildrenState.ts';
9
- import { createComputedExpression } from '../../lib/reactivity/createComputedExpression.ts';
10
20
  import type { MaterializedChildren } from '../../lib/reactivity/materializeCurrentStateChildren.ts';
11
21
  import { materializeCurrentStateChildren } from '../../lib/reactivity/materializeCurrentStateChildren.ts';
12
22
  import type { CurrentState } from '../../lib/reactivity/node-state/createCurrentState.ts';
@@ -20,20 +30,18 @@ import type {
20
30
  } from '../../parse/model/RepeatRangeDefinition.ts';
21
31
  import type {
22
32
  AnyDescendantNode,
23
- DescendantNodeParent,
24
33
  DescendantNodeSharedStateSpec,
25
34
  } from '../abstract/DescendantNode.ts';
26
35
  import { DescendantNode } from '../abstract/DescendantNode.ts';
27
- import type { RepeatRange } from '../hierarchy.ts';
28
- import type { NodeID } from '../identity.ts';
36
+ import type { GeneralParentNode, RepeatRange } from '../hierarchy.ts';
29
37
  import type { EvaluationContext } from '../internal-api/EvaluationContext.ts';
30
- import type { SubscribableDependency } from '../internal-api/SubscribableDependency.ts';
38
+ import type { ClientReactiveSubmittableParentNode } from '../internal-api/submission/ClientReactiveSubmittableParentNode.ts';
31
39
  import { RepeatInstance, type RepeatDefinition } from './RepeatInstance.ts';
32
40
 
33
41
  interface RepeatRangeStateSpec extends DescendantNodeSharedStateSpec {
34
42
  readonly hint: null;
35
43
  readonly label: Accessor<TextRange<'label'> | null>;
36
- readonly children: Accessor<readonly NodeID[]>;
44
+ readonly children: Accessor<readonly FormNodeID[]>;
37
45
  readonly valueOptions: null;
38
46
  readonly value: null;
39
47
  }
@@ -45,59 +53,48 @@ type BaseRepeatRangeNodeType<Definition extends AnyRepeatRangeDefinition> =
45
53
  : 'repeat-range:uncontrolled';
46
54
 
47
55
  export abstract class BaseRepeatRange<Definition extends AnyRepeatRangeDefinition>
48
- extends DescendantNode<Definition, RepeatRangeStateSpec, RepeatInstance>
49
- implements BaseRepeatRangeNode, EvaluationContext, SubscribableDependency
56
+ extends DescendantNode<Definition, RepeatRangeStateSpec, GeneralParentNode, RepeatInstance>
57
+ implements
58
+ BaseRepeatRangeNode,
59
+ XFormsXPathNodeRange,
60
+ EvaluationContext,
61
+ ClientReactiveSubmittableParentNode<RepeatInstance>
50
62
  {
63
+ protected readonly childrenState: ChildrenState<RepeatInstance>;
64
+
51
65
  /**
52
66
  * A repeat range doesn't have a corresponding primary instance element of its
53
- * own, and its instances are appended to the range's parent element. During
54
- * creation of the initial primary instance state and DOM trees, we _could_
55
- * reliably append all of the range's instances in order as the definition
56
- * tree is recursed. But that would fail to handle some instance addition
57
- * cases afterwards.
67
+ * own. It is represented in the following ways:
58
68
  *
59
- * Most notably, we need to know where in the primary instance tree to append
60
- * instances created for a range which is currently empty. As a lucky
61
- * coincidence, this need coincides with the ability to add instances at any
62
- * arbitrary index within the range. In each case, we can reference a primary
63
- * instance DOM node which will become the new instance's preceding sibling.
64
- * Where the range is empty, we use this {@link Comment} node (itself created
65
- * and appended during range initialization) in lieu of a nonexistent
66
- * preceding instance's {@link contextNode}.
69
+ * - As a comment node (in terms of XPath semantics), immediately preceding
70
+ * the repeat range's {@link RepeatInstance | repeat instances} (if it
71
+ * presently has any; as a placeholder where they may be appended
72
+ * otherwise). This is necessary to support certain ODK XForms functionality
73
+ * where an expression is expected to be evaluated against "repeats" as a
74
+ * conceptual unit. Most typically, this includes:
67
75
  *
68
- * @todo We likely want to remove these during submission serialization.
69
- * @todo Can we use a
70
- * {@link https://developer.mozilla.org/en-US/docs/Web/API/Range | DOM Range}
71
- * instead?
72
- */
73
- protected readonly anchorNode: Comment;
74
-
75
- protected readonly childrenState: ChildrenState<RepeatInstance>;
76
-
77
- /**
78
- * Provides an {@link EvaluationContext} from which to evaluate expressions
79
- * where some LocationPath sub-expressions may be **relative to the repeat
80
- * range itself**. This is useful for evaluation of expressions where:
76
+ * - `jr:count` expressions associated with the repeat's body element
77
+ * - `relevant` bind computations associated with the repeat's nodeset
81
78
  *
82
- * - the expression is typically contextualized to any of its
83
- * {@link RepeatInstance} children, but it presently has none (i.e.
84
- * `relevant`)
79
+ * - As a subtree with {@link RepeatInstance | repeat instance} **children**,
80
+ * in service of the client-facing {@link RepeatRangeNode} API (and with the
81
+ * same structural semantics internally)
85
82
  *
86
- * - the expression is conceptually intended to be evaluated in the context of
87
- * the repeat range itself (i.e. `jr:count`)
88
- */
89
- protected readonly selfEvaluationContext: EvaluationContext & {
90
- readonly contextNode: Comment;
91
- };
92
-
93
- /**
94
- * @see {@link isSelfRelevant}
83
+ * Ultimately, this means there is a fundamental impedance mismatch between
84
+ * two representations which are either necessary (XPath) or high value
85
+ * (providing a coherent mental model for clients and the engine
86
+ * implementation servicing that client-facing model).
87
+ *
88
+ * In recognition that this is a truly odd mix of inherent and incidental
89
+ * complexity, here we use the special {@link XFormsXPathNodeRangeKind}
90
+ * branded type as a dedicated point of (internal) documentation where the two
91
+ * models diverge.
95
92
  */
96
- protected readonly isEmptyRangeSelfRelevant: Accessor<boolean>;
93
+ override readonly [XPathNodeKindKey]: XFormsXPathNodeRangeKind = XFORMS_XPATH_NODE_RANGE_KIND;
97
94
 
98
95
  // InstanceNode
99
96
  protected readonly state: SharedNodeState<RepeatRangeStateSpec>;
100
- protected override engineState: EngineState<RepeatRangeStateSpec>;
97
+ protected readonly engineState: EngineState<RepeatRangeStateSpec>;
101
98
 
102
99
  // DescendantNode
103
100
  /**
@@ -108,49 +105,6 @@ export abstract class BaseRepeatRange<Definition extends AnyRepeatRangeDefinitio
108
105
  */
109
106
  declare isSelfReadonly: Accessor<boolean>;
110
107
 
111
- /**
112
- * A repeat range does not exist in the primary instance tree. A `relevant`
113
- * expression applies to each {@link RepeatInstance} child of the repeat
114
- * range. Determining whether a repeat range itself "is relevant" isn't a
115
- * concept the spec addresses, but it may be used by clients to determine
116
- * whether to allow interaction with the range (e.g. by adding a repeat
117
- * instance, or presenting the range's label when empty).
118
- *
119
- * As a naive first pass, it seems like the heuristic for this should be:
120
- *
121
- * 1. Does the repeat range have any repeat instance children?
122
- *
123
- * - If yes, go to 2.
124
- * - If no, go to 3.
125
- *
126
- * 2. Does one or more of those children return `true` for the node's
127
- * `relevant` expression (i.e. is the repeat instance "self relevant")?
128
- *
129
- * 3. Does the relevant expression return `true` for the repeat range itself
130
- * (where, at least for now, the context of that evaluation would be the
131
- * repeat range's {@link anchorNode} to ensure correct relative expressions
132
- * resolve correctly)?
133
- *
134
- * @todo While (3) is proactively implemented, there isn't presently a test
135
- * exercising it. It felt best for now to surface this for discussion in
136
- * review to validate that it's going in the right direction.
137
- *
138
- * @todo While (2) **is actually tested**, the tests currently in place behave
139
- * the same way with only the logic for (3), regardless of whether the repeat
140
- * range actually has any repeat instance children. It's unclear (a) if that's
141
- * a preferable simplification and (b) how that might affect performance (in
142
- * theory it could vary depending on form structure and runtime state).
143
- */
144
- override readonly isSelfRelevant: Accessor<boolean> = () => {
145
- const instances = this.childrenState.getChildren();
146
-
147
- if (instances.length > 0) {
148
- return instances.some((instance) => instance.isSelfRelevant());
149
- }
150
-
151
- return this.isEmptyRangeSelfRelevant();
152
- };
153
-
154
108
  // BaseRepeatRangeNode
155
109
  abstract override readonly nodeType: BaseRepeatRangeNodeType<Definition>;
156
110
 
@@ -193,7 +147,9 @@ export abstract class BaseRepeatRange<Definition extends AnyRepeatRangeDefinitio
193
147
 
194
148
  abstract override readonly validationState: AncestorNodeValidationState;
195
149
 
196
- constructor(parent: DescendantNodeParent<Definition>, definition: Definition) {
150
+ readonly submissionState: SubmissionState;
151
+
152
+ constructor(parent: GeneralParentNode, definition: Definition) {
197
153
  super(parent, definition);
198
154
 
199
155
  const repeatRange = this as AnyDescendantNode as RepeatRange;
@@ -202,28 +158,6 @@ export abstract class BaseRepeatRange<Definition extends AnyRepeatRangeDefinitio
202
158
 
203
159
  this.childrenState = childrenState;
204
160
 
205
- this.anchorNode = this.contextNode.ownerDocument.createComment(
206
- `Begin repeat range: ${definition.nodeset}`
207
- );
208
- this.contextNode.append(this.anchorNode);
209
-
210
- this.selfEvaluationContext = {
211
- scope: this.scope,
212
- evaluator: this.evaluator,
213
- root: this.root,
214
- contextReference: this.contextReference,
215
- contextNode: this.anchorNode,
216
-
217
- getSubscribableDependenciesByReference: (reference) => {
218
- return repeatRange.getSubscribableDependenciesByReference(reference);
219
- },
220
- };
221
-
222
- this.isEmptyRangeSelfRelevant = createComputedExpression(
223
- this.selfEvaluationContext,
224
- definition.bind.relevant
225
- );
226
-
227
161
  const sharedStateOptions = {
228
162
  clientStateFactory: this.engineConfig.stateFactory,
229
163
  };
@@ -252,16 +186,13 @@ export abstract class BaseRepeatRange<Definition extends AnyRepeatRangeDefinitio
252
186
  state.currentState,
253
187
  childrenState
254
188
  );
189
+ this.submissionState = createNodeRangeSubmissionState(this);
255
190
  }
256
191
 
257
192
  protected getLastIndex(): number {
258
193
  return this.engineState.children.length - 1;
259
194
  }
260
195
 
261
- protected override initializeContextNode(parentContextNode: Element): Element {
262
- return parentContextNode;
263
- }
264
-
265
196
  getInstanceIndex(instance: RepeatInstance): number {
266
197
  return this.engineState.children.indexOf(instance.nodeId);
267
198
  }
@@ -289,9 +220,7 @@ export abstract class BaseRepeatRange<Definition extends AnyRepeatRangeDefinitio
289
220
 
290
221
  return definitions.reduce<RepeatInstance[]>((acc, definition) => {
291
222
  const precedingInstance = acc[acc.length - 1] ?? initialPrecedingInstance;
292
- const precedingPrimaryInstanceNode = precedingInstance?.contextNode ?? this.anchorNode;
293
223
  const newInstance = new RepeatInstance(repeatRange, definition, {
294
- precedingPrimaryInstanceNode,
295
224
  precedingInstance,
296
225
  });
297
226
 
@@ -331,16 +260,6 @@ export abstract class BaseRepeatRange<Definition extends AnyRepeatRangeDefinitio
331
260
  });
332
261
  }
333
262
 
334
- override subscribe(): void {
335
- super.subscribe();
336
-
337
- // Subscribing to children can support reactive expressions dependent on the
338
- // repeat range itself (e.g. `count()`).
339
- this.childrenState.getChildren().forEach((child) => {
340
- child.subscribe();
341
- });
342
- }
343
-
344
263
  getChildren(): readonly RepeatInstance[] {
345
264
  return this.childrenState.getChildren();
346
265
  }
@@ -1,12 +1,17 @@
1
+ import { XPathNodeKindKey } from '@getodk/xpath';
1
2
  import type { Accessor } from 'solid-js';
2
3
  import { createComputed, createSignal, on } from 'solid-js';
4
+ import type { FormNodeID } from '../../client/identity.ts';
3
5
  import type {
4
6
  RepeatDefinition,
5
7
  RepeatInstanceNode,
6
8
  RepeatInstanceNodeAppearances,
7
9
  } from '../../client/repeat/RepeatInstanceNode.ts';
10
+ import type { SubmissionState } from '../../client/submission/SubmissionState.ts';
8
11
  import type { TextRange } from '../../client/TextRange.ts';
9
12
  import type { AncestorNodeValidationState } from '../../client/validation.ts';
13
+ import type { XFormsXPathElement } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
14
+ import { createParentNodeSubmissionState } from '../../lib/client-reactivity/submission/createParentNodeSubmissionState.ts';
10
15
  import type { ChildrenState } from '../../lib/reactivity/createChildrenState.ts';
11
16
  import { createChildrenState } from '../../lib/reactivity/createChildrenState.ts';
12
17
  import type { MaterializedChildren } from '../../lib/reactivity/materializeCurrentStateChildren.ts';
@@ -20,36 +25,40 @@ import { createAggregatedViolations } from '../../lib/reactivity/validation/crea
20
25
  import type { DescendantNodeSharedStateSpec } from '../abstract/DescendantNode.ts';
21
26
  import { DescendantNode } from '../abstract/DescendantNode.ts';
22
27
  import { buildChildren } from '../children.ts';
23
- import type { AnyChildNode, GeneralChildNode, RepeatRange } from '../hierarchy.ts';
24
- import type { NodeID } from '../identity.ts';
28
+ import type { GeneralChildNode, RepeatRange } from '../hierarchy.ts';
25
29
  import type { EvaluationContext } from '../internal-api/EvaluationContext.ts';
26
- import type { SubscribableDependency } from '../internal-api/SubscribableDependency.ts';
30
+ import type { ClientReactiveSubmittableParentNode } from '../internal-api/submission/ClientReactiveSubmittableParentNode.ts';
27
31
 
28
32
  export type { RepeatDefinition };
29
33
 
30
34
  interface RepeatInstanceStateSpec extends DescendantNodeSharedStateSpec {
31
35
  readonly label: Accessor<TextRange<'label'> | null>;
32
36
  readonly hint: null;
33
- readonly children: Accessor<readonly NodeID[]>;
37
+ readonly children: Accessor<readonly FormNodeID[]>;
34
38
  readonly valueOptions: null;
35
39
  readonly value: null;
36
40
  }
37
41
 
38
42
  interface RepeatInstanceOptions {
39
- readonly precedingPrimaryInstanceNode: Comment | Element;
40
43
  readonly precedingInstance: RepeatInstance | null;
41
44
  }
42
45
 
43
46
  export class RepeatInstance
44
- extends DescendantNode<RepeatDefinition, RepeatInstanceStateSpec, GeneralChildNode>
45
- implements RepeatInstanceNode, EvaluationContext, SubscribableDependency
47
+ extends DescendantNode<RepeatDefinition, RepeatInstanceStateSpec, RepeatRange, GeneralChildNode>
48
+ implements
49
+ RepeatInstanceNode,
50
+ XFormsXPathElement,
51
+ EvaluationContext,
52
+ ClientReactiveSubmittableParentNode<GeneralChildNode>
46
53
  {
47
54
  private readonly childrenState: ChildrenState<GeneralChildNode>;
48
55
  private readonly currentIndex: Accessor<number>;
49
56
 
57
+ override readonly [XPathNodeKindKey] = 'element';
58
+
50
59
  // InstanceNode
51
60
  protected readonly state: SharedNodeState<RepeatInstanceStateSpec>;
52
- protected override engineState: EngineState<RepeatInstanceStateSpec>;
61
+ protected readonly engineState: EngineState<RepeatInstanceStateSpec>;
53
62
 
54
63
  /**
55
64
  * @todo Should we special case repeat `readonly` inheritance the same way
@@ -89,6 +98,7 @@ export class RepeatInstance
89
98
  GeneralChildNode
90
99
  >;
91
100
  readonly validationState: AncestorNodeValidationState;
101
+ readonly submissionState: SubmissionState;
92
102
 
93
103
  constructor(
94
104
  override readonly parent: RepeatRange,
@@ -113,9 +123,6 @@ export class RepeatInstance
113
123
  const childrenState = createChildrenState<RepeatInstance, GeneralChildNode>(this);
114
124
 
115
125
  this.childrenState = childrenState;
116
-
117
- options.precedingPrimaryInstanceNode.after(this.contextNode);
118
-
119
126
  this.currentIndex = currentIndex;
120
127
 
121
128
  const sharedStateOptions = {
@@ -166,48 +173,15 @@ export class RepeatInstance
166
173
  // other reactive implementations of specific XForms semantics)?
167
174
  const computeCurrentIndex = parent.getInstanceIndex.bind(parent, this);
168
175
 
169
- createComputed(on(computeCurrentIndex, setCurrentIndex, { defer: true }));
176
+ createComputed(on<number, number>(computeCurrentIndex, setCurrentIndex, { defer: true }));
170
177
  });
171
178
 
172
179
  childrenState.setChildren(buildChildren(this));
173
180
  this.validationState = createAggregatedViolations(this, sharedStateOptions);
174
- }
175
-
176
- protected override initializeContextNode(parentContextNode: Element, nodeName: string): Element {
177
- return this.createContextNode(parentContextNode, nodeName);
178
- }
179
-
180
- override subscribe(): void {
181
- super.subscribe();
182
- this.currentIndex();
181
+ this.submissionState = createParentNodeSubmissionState(this);
183
182
  }
184
183
 
185
184
  getChildren(): readonly GeneralChildNode[] {
186
185
  return this.childrenState.getChildren();
187
186
  }
188
-
189
- /**
190
- * Performs repeat instance node-specific removal logic, then general node
191
- * removal logic, in that order:
192
- *
193
- * 1. At present, before any reactive state change is performed, the repeat
194
- * instance's {@link contextNode} is removed from the primary instance's
195
- * XML DOM backing store (which also removes any descendant nodes from that
196
- * store, as a side effect). This behavior may become unnecessary if/when
197
- * we phase out use of this XML DOM backing store. This should be peformed
198
- * first, so that any following reactive logic which evaluates affected
199
- * XPath expressions will be performed against a state consistent with the
200
- * repeat instance's removal (and that of its XML DOM descendants).
201
- *
202
- * 2. Performs any remaining removal logic as defined in
203
- * {@link DescendantNode.remove}.
204
- *
205
- * These removal steps **must also** occur before any update to the parent
206
- * {@link RepeatRange}'s reactive children state.
207
- */
208
- override remove(this: AnyChildNode): void {
209
- this.contextNode.remove();
210
-
211
- super.remove();
212
- }
213
187
  }
@@ -2,24 +2,22 @@ import { createComputed } from 'solid-js';
2
2
  import type { RepeatRangeNodeAppearances } from '../../client/repeat/BaseRepeatRangeNode.ts';
3
3
  import type { RepeatRangeControlledNode } from '../../client/repeat/RepeatRangeControlledNode.ts';
4
4
  import type { AncestorNodeValidationState } from '../../client/validation.ts';
5
+ import type { XFormsXPathNodeRange } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
5
6
  import { createComputedExpression } from '../../lib/reactivity/createComputedExpression.ts';
6
7
  import { createAggregatedViolations } from '../../lib/reactivity/validation/createAggregatedViolations.ts';
7
8
  import type { ControlledRepeatRangeDefinition } from '../../parse/model/RepeatRangeDefinition.ts';
8
9
  import type { GeneralParentNode } from '../hierarchy.ts';
9
10
  import type { EvaluationContext } from '../internal-api/EvaluationContext.ts';
10
- import type { SubscribableDependency } from '../internal-api/SubscribableDependency.ts';
11
11
  import { BaseRepeatRange } from './BaseRepeatRange.ts';
12
12
  import type { RepeatDefinition } from './RepeatInstance.ts';
13
13
 
14
14
  export class RepeatRangeControlled
15
15
  extends BaseRepeatRange<ControlledRepeatRangeDefinition>
16
- implements RepeatRangeControlledNode, EvaluationContext, SubscribableDependency
16
+ implements RepeatRangeControlledNode, XFormsXPathNodeRange, EvaluationContext
17
17
  {
18
18
  // RepeatRangeControlledNode
19
19
  readonly nodeType = 'repeat-range:controlled';
20
-
21
20
  readonly appearances: RepeatRangeNodeAppearances;
22
-
23
21
  readonly validationState: AncestorNodeValidationState;
24
22
 
25
23
  constructor(parent: GeneralParentNode, definition: ControlledRepeatRangeDefinition) {
@@ -37,7 +35,9 @@ export class RepeatRangeControlled
37
35
  private initializeControlledChildrenState(definition: ControlledRepeatRangeDefinition): void {
38
36
  this.scope.runTask(() => {
39
37
  const { count, instances, template } = definition;
40
- const computeCount = createComputedExpression(this.selfEvaluationContext, count);
38
+ const computeCount = createComputedExpression(this, count, {
39
+ defaultValue: 0,
40
+ });
41
41
 
42
42
  createComputed<number>((previousCount) => {
43
43
  let currentCount = computeCount();
@@ -1,24 +1,22 @@
1
1
  import type { RepeatRangeNodeAppearances } from '../../client/repeat/BaseRepeatRangeNode.ts';
2
2
  import type { RepeatRangeUncontrolledNode } from '../../client/repeat/RepeatRangeUncontrolledNode.ts';
3
3
  import type { AncestorNodeValidationState } from '../../client/validation.ts';
4
+ import type { XFormsXPathNodeRange } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
4
5
  import { createAggregatedViolations } from '../../lib/reactivity/validation/createAggregatedViolations.ts';
5
6
  import type { UncontrolledRepeatRangeDefinition } from '../../parse/model/RepeatRangeDefinition.ts';
6
7
  import type { GeneralParentNode } from '../hierarchy.ts';
7
8
  import type { EvaluationContext } from '../internal-api/EvaluationContext.ts';
8
- import type { SubscribableDependency } from '../internal-api/SubscribableDependency.ts';
9
9
  import type { Root } from '../Root.ts';
10
10
  import { BaseRepeatRange } from './BaseRepeatRange.ts';
11
11
  import { RepeatInstance } from './RepeatInstance.ts';
12
12
 
13
13
  export class RepeatRangeUncontrolled
14
14
  extends BaseRepeatRange<UncontrolledRepeatRangeDefinition>
15
- implements RepeatRangeUncontrolledNode, EvaluationContext, SubscribableDependency
15
+ implements RepeatRangeUncontrolledNode, XFormsXPathNodeRange, EvaluationContext
16
16
  {
17
17
  // RepeatRangeUncontrolledNode
18
18
  readonly nodeType = 'repeat-range:uncontrolled';
19
-
20
19
  readonly appearances: RepeatRangeNodeAppearances;
21
-
22
20
  readonly validationState: AncestorNodeValidationState;
23
21
 
24
22
  constructor(parent: GeneralParentNode, definition: UncontrolledRepeatRangeDefinition) {
@@ -1,7 +1,7 @@
1
1
  import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
2
2
  import { getBlobText } from '@getodk/common/lib/web-compat/blob.ts';
3
- import type { FetchResource, FetchResourceResponse } from '../client/EngineConfig.ts';
4
3
  import type { FormResource } from '../client/index.ts';
4
+ import type { FetchResource, FetchResourceResponse } from '../client/resources.ts';
5
5
 
6
6
  export type { FetchResource, FetchResourceResponse, FormResource };
7
7
 
@@ -9,7 +9,7 @@ export class TextChunk implements ClientTextChunk {
9
9
  }
10
10
 
11
11
  get language(): ActiveLanguage {
12
- return this.context.activeLanguage;
12
+ return this.context.getActiveLanguage();
13
13
  }
14
14
 
15
15
  constructor(
@@ -1,5 +1,9 @@
1
1
  import { UnsupportedControl } from '../abstract/UnsupportedControl.ts';
2
+ import type { ValueContext } from '../internal-api/ValueContext.ts';
2
3
 
3
- export class RangeControl extends UnsupportedControl<'range'> {
4
+ export class RangeControl extends UnsupportedControl<'range'> implements ValueContext<unknown> {
4
5
  readonly nodeType = 'range';
6
+
7
+ // ValueContext
8
+ readonly contextNode = this;
5
9
  }
@@ -1,5 +1,9 @@
1
1
  import { UnsupportedControl } from '../abstract/UnsupportedControl.ts';
2
+ import type { ValueContext } from '../internal-api/ValueContext.ts';
2
3
 
3
- export class RankControl extends UnsupportedControl<'rank'> {
4
+ export class RankControl extends UnsupportedControl<'rank'> implements ValueContext<unknown> {
4
5
  readonly nodeType = 'rank';
6
+
7
+ // ValueContext
8
+ readonly contextNode = this;
5
9
  }
@@ -1,5 +1,9 @@
1
1
  import { UnsupportedControl } from '../abstract/UnsupportedControl.ts';
2
+ import type { ValueContext } from '../internal-api/ValueContext.ts';
2
3
 
3
- export class UploadControl extends UnsupportedControl<'upload'> {
4
+ export class UploadControl extends UnsupportedControl<'upload'> implements ValueContext<unknown> {
4
5
  readonly nodeType = 'upload';
6
+
7
+ // ValueContext
8
+ readonly contextNode = this;
5
9
  }
@@ -0,0 +1,22 @@
1
+ import type { XFormsItextTranslationMap, XFormsSecondaryInstanceMap } from '@getodk/xpath';
2
+ import { XFormsXPathEvaluator } from '@getodk/xpath';
3
+ import type { PrimaryInstance } from '../../instance/PrimaryInstance.ts';
4
+ import type { ItextTranslationRootDefinition } from '../../parse/model/ItextTranslation/ItextTranslationRootDefinition.ts';
5
+ import type { SecondaryInstanceRootDefinition } from '../../parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts';
6
+ import { engineDOMAdapter } from './adapter/engineDOMAdapter.ts';
7
+ import type { EngineXPathNode } from './adapter/kind.ts';
8
+
9
+ interface EngineXPathEvaluatorOptions {
10
+ readonly rootNode: PrimaryInstance;
11
+ readonly itextTranslationsByLanguage: XFormsItextTranslationMap<ItextTranslationRootDefinition>;
12
+ readonly secondaryInstancesById: XFormsSecondaryInstanceMap<SecondaryInstanceRootDefinition>;
13
+ }
14
+
15
+ export class EngineXPathEvaluator extends XFormsXPathEvaluator<EngineXPathNode> {
16
+ constructor(options: EngineXPathEvaluatorOptions) {
17
+ super({
18
+ domAdapter: engineDOMAdapter,
19
+ ...options,
20
+ });
21
+ }
22
+ }