@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,126 @@
1
+ import type {
2
+ XPathAttributeKind,
3
+ XPathCommentKind,
4
+ XPathDocumentKind,
5
+ XPathElementKind,
6
+ XPathTextKind,
7
+ } from '@getodk/xpath';
8
+ import { XPathNodeKindKey } from '@getodk/xpath';
9
+
10
+ const XFORMS_XPATH_NODE_RANGE_BRAND = Symbol('XFORMS_XPATH_NODE_RANGE_BRAND');
11
+
12
+ /**
13
+ * To be used with any engine representation of a "range" of contiguous child
14
+ * nodes (also somewhat analogous to a DOM "fragment"). This mapping is
15
+ * conceptually disjoint, but serves an important purpose:
16
+ *
17
+ * - While such a "range" may increase the hierarchical depth of an
18
+ * engine-internal representation, it **DOES NOT** contribute the same
19
+ * hierarchy in XPath evaluation semantics.
20
+ * - Such a "range" may be treated as a distinct context node for evaluating an
21
+ * expression. This most cleanly maps to XPath's comment semantics in that it
22
+ * allows the "range" to have a clear document position (hierarchically a
23
+ * child of its parent element; sequentially a sibling to that parent's other
24
+ * child nodes).
25
+ *
26
+ * (Note: while this is phrased as an abstract concept, it is intended to
27
+ * correspond directly to the engine's "repeat range" concept. The specific type
28
+ * is not referenced here because they have an inverse relationship in the
29
+ * module/type graph.)
30
+ */
31
+ // prettier-ignore
32
+ export type XFormsXPathNodeRangeKind =
33
+ & 'comment'
34
+ & { readonly [XFORMS_XPATH_NODE_RANGE_BRAND]: true };
35
+
36
+ export const XFORMS_XPATH_NODE_RANGE_KIND = 'comment' as XFormsXPathNodeRangeKind;
37
+
38
+ // prettier-ignore
39
+ export type XFormsXPathNodeKind =
40
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
41
+ | XPathDocumentKind
42
+ | XFormsXPathNodeRangeKind
43
+ | XPathElementKind
44
+ | XPathAttributeKind
45
+ | XPathTextKind
46
+ | XPathCommentKind;
47
+
48
+ export interface XFormsXPathNode {
49
+ readonly [XPathNodeKindKey]: XFormsXPathNodeKind;
50
+ readonly rootDocument: XFormsXPathDocument;
51
+ readonly root: XFormsXPathElement;
52
+
53
+ getXPathChildNodes(this: XFormsXPathNode): readonly XFormsXPathDescendantNode[];
54
+ getXPathValue(this: XFormsXPathNode): string;
55
+ }
56
+
57
+ export interface XFormsXPathDocument extends XFormsXPathNode {
58
+ readonly [XPathNodeKindKey]: XPathDocumentKind;
59
+ }
60
+
61
+ export interface XFormsXPathElement extends XFormsXPathNode {
62
+ readonly [XPathNodeKindKey]: XPathElementKind;
63
+ }
64
+
65
+ /**
66
+ * @see {@link XFormsXPathNodeRangeKind}
67
+ */
68
+ export interface XFormsXPathNodeRange extends XFormsXPathNode {
69
+ readonly [XPathNodeKindKey]: XFormsXPathNodeRangeKind;
70
+ }
71
+
72
+ export interface XFormsXPathAttribute extends XFormsXPathNode {
73
+ readonly [XPathNodeKindKey]: XPathAttributeKind;
74
+ }
75
+
76
+ export interface XFormsXPathText extends XFormsXPathNode {
77
+ readonly [XPathNodeKindKey]: XPathTextKind;
78
+ }
79
+
80
+ export interface XFormsXPathComment extends XFormsXPathNode {
81
+ readonly [XPathNodeKindKey]: XPathCommentKind;
82
+ }
83
+
84
+ // prettier-ignore
85
+ export type XPathNamedNodeKind =
86
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
87
+ | XPathElementKind
88
+ | XPathAttributeKind;
89
+
90
+ export interface XFormsXPathNamedNode extends XFormsXPathNode {
91
+ readonly [XPathNodeKindKey]: XPathNamedNodeKind;
92
+ }
93
+
94
+ // prettier-ignore
95
+ export type XFormsXPathDescendantNodeKind =
96
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
97
+ | XFormsXPathNodeRangeKind
98
+ | XPathElementKind
99
+ | XPathTextKind
100
+ | XPathCommentKind;
101
+
102
+ export interface XFormsXPathDescendantNode extends XFormsXPathNode {
103
+ readonly [XPathNodeKindKey]: XFormsXPathDescendantNodeKind;
104
+ }
105
+
106
+ // prettier-ignore
107
+ export type XFormsXPathPrimaryInstanceNodeKind =
108
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
109
+ | XPathDocumentKind
110
+ | XFormsXPathNodeRangeKind
111
+ | XPathElementKind
112
+ | XPathTextKind;
113
+
114
+ export interface XFormsXPathPrimaryInstanceNode extends XFormsXPathNode {
115
+ readonly [XPathNodeKindKey]: XFormsXPathPrimaryInstanceNodeKind;
116
+ }
117
+
118
+ // prettier-ignore
119
+ export type XFormsXPathPrimaryInstanceDescendantNodeKind =
120
+ | XFormsXPathNodeRangeKind
121
+ | XPathElementKind
122
+ | XPathTextKind;
123
+
124
+ export interface XFormsXPathPrimaryInstanceDescendantNode extends XFormsXPathNode {
125
+ readonly [XPathNodeKindKey]: XFormsXPathPrimaryInstanceDescendantNodeKind;
126
+ }
@@ -0,0 +1,57 @@
1
+ import type { XPathDOMAdapter } from '@getodk/xpath';
2
+ import type { EngineXPathNode } from './kind.ts';
3
+ import { getEngineXPathNodeKind, isEngineXPathNode } from './kind.ts';
4
+ import {
5
+ getEngineProcessingInstructionName,
6
+ getEngineXPathNodeLocalName,
7
+ getEngineXPathNodeNamespaceURI,
8
+ getEngineXPathNodeQualifiedName,
9
+ resolveEngineXPathNodeNamespaceURI,
10
+ } from './names.ts';
11
+ import {
12
+ compareDocumentOrder,
13
+ getChildElements,
14
+ getChildNodes,
15
+ getContainingEngineXPathDocument,
16
+ getEngineXPathAttributes,
17
+ getNamespaceDeclarations,
18
+ getNextSiblingElement,
19
+ getNextSiblingNode,
20
+ getParentNode,
21
+ getPreviousSiblingElement,
22
+ getPreviousSiblingNode,
23
+ isDescendantNode,
24
+ } from './traversal.ts';
25
+ import { getEngineXPathNodeValue } from './values.ts';
26
+
27
+ export interface EngineDOMAdapter extends XPathDOMAdapter<EngineXPathNode> {}
28
+
29
+ export const engineDOMAdapter: EngineDOMAdapter = {
30
+ // XPathNodeKindAdapter
31
+ getNodeKind: getEngineXPathNodeKind,
32
+ isXPathNode: isEngineXPathNode,
33
+
34
+ // XPathNameAdapter
35
+ getLocalName: getEngineXPathNodeLocalName,
36
+ getNamespaceURI: getEngineXPathNodeNamespaceURI,
37
+ getQualifiedName: getEngineXPathNodeQualifiedName,
38
+ getProcessingInstructionName: getEngineProcessingInstructionName,
39
+ resolveNamespaceURI: resolveEngineXPathNodeNamespaceURI,
40
+
41
+ // XPathValueAdapter
42
+ getNodeValue: getEngineXPathNodeValue,
43
+
44
+ // XPathTraversalAdapter
45
+ compareDocumentOrder,
46
+ getAttributes: getEngineXPathAttributes,
47
+ getChildElements: getChildElements,
48
+ getChildNodes: getChildNodes,
49
+ getContainingDocument: getContainingEngineXPathDocument,
50
+ getNamespaceDeclarations: getNamespaceDeclarations,
51
+ getNextSiblingElement: getNextSiblingElement,
52
+ getNextSiblingNode: getNextSiblingNode,
53
+ getParentNode: getParentNode,
54
+ getPreviousSiblingElement: getPreviousSiblingElement,
55
+ getPreviousSiblingNode: getPreviousSiblingNode,
56
+ isDescendantNode: isDescendantNode,
57
+ };
@@ -0,0 +1,114 @@
1
+ import type { XPathNodeKind } from '@getodk/xpath';
2
+ import { XPathNodeKindKey } from '@getodk/xpath';
3
+ import type {
4
+ AnyChildNode,
5
+ AnyNode,
6
+ AnyParentNode,
7
+ AnyValueNode,
8
+ } from '../../../instance/hierarchy.ts';
9
+ import type { ValueContext } from '../../../instance/internal-api/ValueContext.ts';
10
+ import type { PrimaryInstance } from '../../../instance/PrimaryInstance.ts';
11
+ import type { ItextTranslationDefinition } from '../../../parse/model/ItextTranslation/ItextTranslationDefinition.ts';
12
+ import type { ItextTranslationRootDefinition } from '../../../parse/model/ItextTranslation/ItextTranslationRootDefinition.ts';
13
+ import type { SecondaryInstanceDefinition } from '../../../parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts';
14
+ import type { SecondaryInstanceRootDefinition } from '../../../parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts';
15
+ import type { StaticAttribute } from '../static-dom/StaticAttribute.ts';
16
+ import type { StaticDocument } from '../static-dom/StaticDocument.ts';
17
+ import type { StaticElement } from '../static-dom/StaticElement.ts';
18
+ import type { StaticText } from '../static-dom/StaticText.ts';
19
+ import type {
20
+ XFormsXPathComment,
21
+ XFormsXPathDocument,
22
+ XFormsXPathElement,
23
+ XFormsXPathPrimaryInstanceNode,
24
+ } from './XFormsXPathNode.ts';
25
+
26
+ export type PrimaryInstanceXPathNode = Extract<AnyNode, XFormsXPathPrimaryInstanceNode>;
27
+
28
+ export type PrimaryInstanceXPathElement = Extract<AnyChildNode, XFormsXPathElement>;
29
+
30
+ export type PrimaryInstanceXPathComment = Extract<AnyChildNode, XFormsXPathComment>;
31
+
32
+ // prettier-ignore
33
+ export type PrimaryInstanceXPathChildNode =
34
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
35
+ | PrimaryInstanceXPathElement
36
+ | PrimaryInstanceXPathComment;
37
+
38
+ // prettier-ignore
39
+ export type PrimaryInstanceXPathValueElement<Value> =
40
+ & AnyValueNode
41
+ & ValueContext<Value>
42
+ & XFormsXPathElement;
43
+
44
+ // prettier-ignore
45
+ export type EngineXPathDocument =
46
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
47
+ | PrimaryInstance
48
+ | ItextTranslationDefinition
49
+ | SecondaryInstanceDefinition
50
+ | StaticDocument;
51
+
52
+ // prettier-ignore
53
+ export type EngineXPathElement =
54
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
55
+ | PrimaryInstanceXPathElement
56
+ | ItextTranslationRootDefinition
57
+ | SecondaryInstanceRootDefinition
58
+ | StaticElement;
59
+
60
+ // prettier-ignore
61
+ export type EngineXPathComment =
62
+ | PrimaryInstanceXPathComment;
63
+
64
+ // Giving this a type alias anticipates eventually implementing attributes
65
+ // in primary instance state as well
66
+ export type EngineXPathAttribute = StaticAttribute;
67
+
68
+ export type EngineXPathText = StaticText;
69
+
70
+ // prettier-ignore
71
+ export type XFormsXPathChildNode =
72
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
73
+ | EngineXPathElement
74
+ | EngineXPathText
75
+ | EngineXPathComment;
76
+
77
+ // prettier-ignore
78
+ type XPathAdapterParentNode =
79
+ | XFormsXPathDocument
80
+ | XFormsXPathElement;
81
+
82
+ type PrimaryInstanceXPathParentNode = Extract<AnyParentNode, XPathAdapterParentNode>;
83
+
84
+ // prettier-ignore
85
+ export type EngineXPathParentNode =
86
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
87
+ | PrimaryInstanceXPathParentNode
88
+ | ItextTranslationDefinition
89
+ | SecondaryInstanceDefinition
90
+ | ItextTranslationRootDefinition
91
+ | SecondaryInstanceRootDefinition
92
+ | StaticDocument
93
+ | StaticElement;
94
+
95
+ // prettier-ignore
96
+ export type EngineXPathNode =
97
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
98
+ | EngineXPathDocument
99
+ | EngineXPathElement
100
+ | EngineXPathAttribute
101
+ | EngineXPathText
102
+ | EngineXPathComment;
103
+
104
+ export const isEngineXPathNode = (value: unknown): value is EngineXPathNode => {
105
+ return typeof value === 'object' && value != null && XPathNodeKindKey in value;
106
+ };
107
+
108
+ export const getEngineXPathNodeKind = (node: EngineXPathNode): XPathNodeKind => {
109
+ return node[XPathNodeKindKey];
110
+ };
111
+
112
+ export const isEngineXPathElement = (node: EngineXPathNode): node is EngineXPathElement => {
113
+ return getEngineXPathNodeKind(node) === 'element';
114
+ };
@@ -0,0 +1,99 @@
1
+ import {
2
+ ENKETO_NAMESPACE_URI,
3
+ ENKETO_PREFIX,
4
+ FN_NAMESPACE_URI,
5
+ FN_PREFIX,
6
+ HTML_PREFIX,
7
+ JAVAROSA_NAMESPACE_URI,
8
+ JAVAROSA_PREFIX,
9
+ ODK_NAMESPACE_URI,
10
+ ODK_PREFIX,
11
+ OPENROSA_XFORMS_NAMESPACE_URI,
12
+ OPENROSA_XFORMS_PREFIX,
13
+ XFORMS_NAMESPACE_URI,
14
+ XFORMS_PREFIX,
15
+ XHTML_NAMESPACE_URI,
16
+ } from '@getodk/common/constants/xmlns.ts';
17
+ import { XPathFunctionalityNotSupportedError } from '../../../error/XPathFunctionalityNotSupportedError.ts';
18
+ import type { InstanceNode } from '../../../instance/abstract/InstanceNode.ts';
19
+ import type { StaticNode } from '../static-dom/StaticNode.ts';
20
+ import type { EngineXPathNode } from './kind.ts';
21
+ import type { getNamespaceDeclarations } from './traversal.ts';
22
+
23
+ export const getEngineXPathNodeNamespaceURI = (node: EngineXPathNode): string | null => {
24
+ switch (node.nodeType) {
25
+ case 'primary-instance':
26
+ case 'static-text':
27
+ return null;
28
+
29
+ case 'static-attribute':
30
+ case 'static-element':
31
+ return node.namespaceURI;
32
+
33
+ default:
34
+ return XFORMS_NAMESPACE_URI;
35
+ }
36
+ };
37
+
38
+ /**
39
+ * @todo currently, neither {@link InstanceNode} nor {@link StaticNode} account
40
+ * for prefixes in qualified names. This was already a general enough gap that
41
+ * it makes sense to defer to a broader solution as it becomes a priority
42
+ * (likely prompted by a bug report about unexpected behavior of the XPath
43
+ * `name` function).
44
+ */
45
+ export const getEngineXPathNodeQualifiedName = (node: EngineXPathNode): string => {
46
+ return getEngineXPathNodeLocalName(node);
47
+ };
48
+
49
+ export const getEngineXPathNodeLocalName = (node: EngineXPathNode): string => {
50
+ switch (node.nodeType) {
51
+ case 'static-attribute':
52
+ case 'static-element':
53
+ return node.localName;
54
+
55
+ case 'static-document':
56
+ case 'static-text':
57
+ return '';
58
+
59
+ default:
60
+ return node.definition.nodeName;
61
+ }
62
+ };
63
+
64
+ export const getEngineProcessingInstructionName =
65
+ XPathFunctionalityNotSupportedError.createStubImplementation('processing-instruction');
66
+
67
+ /**
68
+ * @todo @see {@link getNamespaceDeclarations}
69
+ */
70
+ export const resolveEngineXPathNodeNamespaceURI = (_: EngineXPathNode, prefix: string | null) => {
71
+ switch (prefix) {
72
+ case null:
73
+ return XFORMS_NAMESPACE_URI;
74
+
75
+ case ENKETO_PREFIX:
76
+ return ENKETO_NAMESPACE_URI;
77
+
78
+ case FN_PREFIX:
79
+ return FN_NAMESPACE_URI;
80
+
81
+ case HTML_PREFIX:
82
+ return XHTML_NAMESPACE_URI;
83
+
84
+ case JAVAROSA_PREFIX:
85
+ return JAVAROSA_NAMESPACE_URI;
86
+
87
+ case ODK_PREFIX:
88
+ return ODK_NAMESPACE_URI;
89
+
90
+ case OPENROSA_XFORMS_PREFIX:
91
+ return OPENROSA_XFORMS_NAMESPACE_URI;
92
+
93
+ case XFORMS_PREFIX:
94
+ return XFORMS_NAMESPACE_URI;
95
+
96
+ default:
97
+ return null;
98
+ }
99
+ };
@@ -0,0 +1,228 @@
1
+ import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
2
+ import { ErrorProductionDesignPendingError } from '../../../error/ErrorProductionDesignPendingError.ts';
3
+ import { XPathFunctionalityPendingError } from '../../../error/XPathFunctionalityPendingError.ts';
4
+ import type { AnyNode } from '../../../instance/hierarchy.ts';
5
+ import type { AnyStaticNode, StaticParentNode } from '../static-dom/StaticNode.ts';
6
+ import type {
7
+ EngineXPathAttribute,
8
+ EngineXPathDocument,
9
+ EngineXPathElement,
10
+ EngineXPathNode,
11
+ EngineXPathParentNode,
12
+ PrimaryInstanceXPathChildNode,
13
+ XFormsXPathChildNode,
14
+ } from './kind.ts';
15
+ import { isEngineXPathElement } from './kind.ts';
16
+
17
+ export const getContainingEngineXPathDocument = (node: EngineXPathNode): EngineXPathDocument => {
18
+ return node.rootDocument;
19
+ };
20
+
21
+ export const getEngineXPathAttributes = (node: EngineXPathNode): Iterable<EngineXPathAttribute> => {
22
+ if (node.nodeType === 'static-element') {
23
+ return node.attributes;
24
+ }
25
+
26
+ return [];
27
+ };
28
+
29
+ /**
30
+ * @todo XML XForms may actually define explicit namespace declarations on
31
+ * non-root elements (i.e. elements other than the form definition's `h:html`,
32
+ * itext `translation`, secondary `instance`). Expressions defined in such forms
33
+ * may also expect to use those namespace declarations. It would even seem
34
+ * likely! Why declare namespaces on a subtree if you don't intend to use them?
35
+ * We don't currently capture namespace declarations below `h:html` in the parse
36
+ * stage (which, if we intend to support the use case, is where we should
37
+ * start).
38
+ *
39
+ * @todo At the very least, we should probably produce a set of default namespace declarations. At least for `h:html`, maybe for other "root" nodes.
40
+ */
41
+ export const getNamespaceDeclarations = (): Iterable<never> => [];
42
+
43
+ export const getParentNode = (node: EngineXPathNode): EngineXPathParentNode | null => {
44
+ if (node.nodeType === 'repeat-instance') {
45
+ return node.parent.parent;
46
+ }
47
+
48
+ return node.parent;
49
+ };
50
+
51
+ export const getChildNodes = (node: EngineXPathNode): readonly XFormsXPathChildNode[] => {
52
+ return node.getXPathChildNodes();
53
+ };
54
+
55
+ export const getChildElements = (node: EngineXPathNode): readonly EngineXPathElement[] => {
56
+ return getChildNodes(node).filter(isEngineXPathElement);
57
+ };
58
+
59
+ export const getPreviousSiblingNode = (node: EngineXPathNode): XFormsXPathChildNode | null => {
60
+ const parent = getParentNode(node);
61
+
62
+ if (parent == null) {
63
+ return null;
64
+ }
65
+
66
+ let previous: EngineXPathNode | null = null;
67
+
68
+ for (const child of getChildNodes(parent)) {
69
+ if (child === node) {
70
+ return previous;
71
+ }
72
+
73
+ previous = child;
74
+ }
75
+
76
+ return null;
77
+ };
78
+
79
+ export const getPreviousSiblingElement = (node: EngineXPathNode): EngineXPathElement | null => {
80
+ const parent = getParentNode(node);
81
+
82
+ if (parent == null) {
83
+ return null;
84
+ }
85
+
86
+ let previous: EngineXPathElement | null = null;
87
+
88
+ for (const child of getChildNodes(parent)) {
89
+ if (child === node) {
90
+ return previous;
91
+ }
92
+
93
+ if (isEngineXPathElement(child)) {
94
+ previous = child;
95
+ }
96
+ }
97
+
98
+ return null;
99
+ };
100
+
101
+ export const getNextSiblingNode = (node: EngineXPathNode): XFormsXPathChildNode | null => {
102
+ const parent = getParentNode(node);
103
+
104
+ if (parent == null) {
105
+ return null;
106
+ }
107
+
108
+ let visitedCurrent = false;
109
+
110
+ for (const child of getChildNodes(parent)) {
111
+ if (child === node) {
112
+ visitedCurrent = true;
113
+ } else if (visitedCurrent) {
114
+ return child;
115
+ }
116
+ }
117
+
118
+ return null;
119
+ };
120
+
121
+ export const getNextSiblingElement = (node: EngineXPathNode): EngineXPathElement | null => {
122
+ const parent = getParentNode(node);
123
+
124
+ if (parent == null) {
125
+ return null;
126
+ }
127
+
128
+ let visitedCurrent = false;
129
+
130
+ for (const child of getChildNodes(parent)) {
131
+ if (child === node) {
132
+ visitedCurrent = true;
133
+ } else if (visitedCurrent && isEngineXPathElement(child)) {
134
+ return child;
135
+ }
136
+ }
137
+
138
+ return null;
139
+ };
140
+
141
+ const isPrimaryInstanceChildNode = (
142
+ node: EngineXPathNode
143
+ ): node is PrimaryInstanceXPathChildNode => {
144
+ switch (node.nodeType) {
145
+ case 'primary-instance':
146
+ case 'static-attribute':
147
+ case 'static-element':
148
+ case 'static-text':
149
+ return false;
150
+
151
+ default:
152
+ return true;
153
+ }
154
+ };
155
+
156
+ const primaryInstanceElementContains = (ancestor: AnyNode, other: AnyNode): boolean => {
157
+ if (other === ancestor) {
158
+ return true;
159
+ }
160
+
161
+ const { parent, root } = other;
162
+
163
+ if (parent == null || parent === root) {
164
+ return false;
165
+ }
166
+
167
+ return primaryInstanceElementContains(ancestor, parent);
168
+ };
169
+
170
+ const staticParentNodeContains = (ancestor: StaticParentNode, other: AnyStaticNode): boolean => {
171
+ if (ancestor === other) {
172
+ return false;
173
+ }
174
+
175
+ const { parent } = other;
176
+
177
+ if (parent == null) {
178
+ return false;
179
+ }
180
+
181
+ return staticParentNodeContains(ancestor, parent);
182
+ };
183
+
184
+ export const isDescendantNode = (ancestor: EngineXPathNode, other: EngineXPathNode) => {
185
+ // TODO: "descendant" semantics != "contains" semantics
186
+ if (ancestor === other) {
187
+ return true;
188
+ }
189
+
190
+ if (ancestor.nodeType === 'primary-instance') {
191
+ return isPrimaryInstanceChildNode(other);
192
+ }
193
+
194
+ if (other.nodeType === 'primary-instance') {
195
+ // TODO: in the event this does somehow occur, this is not the kind of error
196
+ // messaging we want to surface to users! It is, however, exactly the kind
197
+ // of messaging we want to surface to us.
198
+ throw new ErrorProductionDesignPendingError(
199
+ 'Exhaustive check failed: comparing hierarchy of two primary instance documents. It is unclear how this could ever occur. If it has, something may have gone horribly wrong!'
200
+ );
201
+ }
202
+
203
+ if (isPrimaryInstanceChildNode(ancestor)) {
204
+ return isPrimaryInstanceChildNode(other) && primaryInstanceElementContains(ancestor, other);
205
+ }
206
+
207
+ if (isPrimaryInstanceChildNode(other)) {
208
+ return false;
209
+ }
210
+
211
+ switch (ancestor.nodeType) {
212
+ case 'static-attribute':
213
+ case 'static-text':
214
+ return false;
215
+
216
+ case 'static-document':
217
+ case 'static-element':
218
+ break;
219
+
220
+ default:
221
+ throw new UnreachableError(ancestor);
222
+ }
223
+
224
+ return staticParentNodeContains(ancestor, other);
225
+ };
226
+
227
+ export const compareDocumentOrder =
228
+ XPathFunctionalityPendingError.createStubImplementation('compareDocumentOrder');
@@ -0,0 +1,5 @@
1
+ import type { EngineXPathNode } from './kind.ts';
2
+
3
+ export const getEngineXPathNodeValue = (node: EngineXPathNode): string => {
4
+ return node.getXPathValue();
5
+ };
@@ -0,0 +1,33 @@
1
+ import { XPathNodeKindKey } from '@getodk/xpath';
2
+ import type { XFormsXPathAttribute } from '../adapter/XFormsXPathNode.ts';
3
+ import type { StaticElement } from './StaticElement.ts';
4
+ import type { StaticNamedNodeOptions } from './StaticNamedNode.ts';
5
+ import { StaticNamedNode } from './StaticNamedNode.ts';
6
+
7
+ interface StaticAttributeOptions extends StaticNamedNodeOptions {
8
+ readonly value: string;
9
+ }
10
+
11
+ export class StaticAttribute extends StaticNamedNode<'attribute'> implements XFormsXPathAttribute {
12
+ readonly [XPathNodeKindKey] = 'attribute';
13
+ readonly nodeType = 'static-attribute';
14
+ readonly root: StaticElement;
15
+ readonly attributes = [] as const;
16
+ readonly children = null;
17
+ override readonly value: string;
18
+
19
+ constructor(
20
+ override readonly parent: StaticElement,
21
+ options: StaticAttributeOptions
22
+ ) {
23
+ super(parent, options);
24
+
25
+ this.root = parent.root;
26
+ this.value = options.value;
27
+ }
28
+
29
+ // XFormsXPathAttribute
30
+ getXPathValue(): string {
31
+ return this.value;
32
+ }
33
+ }
@@ -0,0 +1,38 @@
1
+ import { XPathNodeKindKey } from '@getodk/xpath';
2
+ import type { XFormsXPathDocument } from '../adapter/XFormsXPathNode.ts';
3
+ import { StaticElement } from './StaticElement.ts';
4
+ import { StaticNode } from './StaticNode.ts';
5
+
6
+ export type StaticDocumentRootFactory<T extends StaticDocument, Root extends StaticElement> = (
7
+ staticDocument: T
8
+ ) => Root;
9
+
10
+ export abstract class StaticDocument<DocumentRoot extends StaticElement = StaticElement>
11
+ extends StaticNode<'document'>
12
+ implements XFormsXPathDocument
13
+ {
14
+ readonly [XPathNodeKindKey] = 'document';
15
+ readonly nodeType = 'static-document';
16
+ readonly rootDocument: StaticDocument;
17
+ readonly root: DocumentRoot;
18
+ readonly isXFormsNamespace: boolean;
19
+ readonly parent = null;
20
+ readonly children: readonly [root: DocumentRoot];
21
+
22
+ constructor(rootFactory: StaticDocumentRootFactory<StaticDocument<DocumentRoot>, DocumentRoot>) {
23
+ super();
24
+
25
+ this.rootDocument = this;
26
+
27
+ const root = rootFactory(this);
28
+
29
+ this.root = root;
30
+ this.isXFormsNamespace = root.isXFormsNamespace;
31
+ this.children = [root];
32
+ }
33
+
34
+ // XFormsXPathDocument
35
+ getXPathValue(): string {
36
+ return this.root.getXPathValue();
37
+ }
38
+ }