@getodk/xforms-engine 0.5.0 → 0.7.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 (425) hide show
  1. package/README.md +1 -1
  2. package/dist/client/BaseNode.d.ts +8 -4
  3. package/dist/client/BaseValueNode.d.ts +8 -4
  4. package/dist/client/GroupNode.d.ts +1 -0
  5. package/dist/client/InputNode.d.ts +32 -3
  6. package/dist/client/ModelValueNode.d.ts +1 -0
  7. package/dist/client/NoteNode.d.ts +24 -7
  8. package/dist/client/RangeNode.d.ts +36 -0
  9. package/dist/client/RankNode.d.ts +46 -0
  10. package/dist/client/RootNode.d.ts +21 -14
  11. package/dist/client/SelectNode.d.ts +47 -25
  12. package/dist/client/SubtreeNode.d.ts +1 -0
  13. package/dist/client/TriggerNode.d.ts +10 -6
  14. package/dist/client/constants.d.ts +11 -12
  15. package/dist/client/form/CreateFormInstance.d.ts +14 -0
  16. package/dist/client/form/EditFormInstance.d.ts +62 -0
  17. package/dist/client/form/FormInstance.d.ts +104 -0
  18. package/dist/client/form/FormInstanceConfig.d.ts +17 -0
  19. package/dist/client/form/FormResource.d.ts +1 -0
  20. package/dist/client/form/LoadForm.d.ts +79 -0
  21. package/dist/client/form/LoadFormResult.d.ts +67 -0
  22. package/dist/client/form/RestoreFormInstance.d.ts +8 -0
  23. package/dist/client/hierarchy.d.ts +5 -5
  24. package/dist/client/index.d.ts +37 -11
  25. package/dist/client/node-types.d.ts +2 -2
  26. package/dist/client/repeat/BaseRepeatRangeNode.d.ts +3 -4
  27. package/dist/client/repeat/RepeatInstanceNode.d.ts +4 -5
  28. package/dist/client/repeat/RepeatRangeControlledNode.d.ts +2 -2
  29. package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +2 -2
  30. package/dist/client/resources.d.ts +1 -1
  31. package/dist/client/serialization/InstanceData.d.ts +12 -0
  32. package/dist/client/serialization/InstanceFile.d.ts +6 -0
  33. package/dist/client/serialization/InstancePayload.d.ts +93 -0
  34. package/dist/client/serialization/InstancePayloadOptions.d.ts +23 -0
  35. package/dist/client/serialization/InstanceState.d.ts +12 -0
  36. package/dist/client/submission/{SubmissionDefinition.d.ts → SubmissionMeta.d.ts} +1 -1
  37. package/dist/client/unsupported/UnsupportedControlNode.d.ts +1 -3
  38. package/dist/entrypoints/FormInstance.d.ts +20 -0
  39. package/dist/entrypoints/FormResult/BaseFormResult.d.ts +22 -0
  40. package/dist/entrypoints/FormResult/BaseInstantiableFormResult.d.ts +25 -0
  41. package/dist/entrypoints/FormResult/FormFailureResult.d.ts +17 -0
  42. package/dist/entrypoints/FormResult/FormSuccessResult.d.ts +15 -0
  43. package/dist/entrypoints/FormResult/FormWarningResult.d.ts +15 -0
  44. package/dist/entrypoints/createInstance.d.ts +9 -0
  45. package/dist/entrypoints/editInstance.d.ts +9 -0
  46. package/dist/entrypoints/index.d.ts +4 -0
  47. package/dist/entrypoints/loadForm.d.ts +4 -0
  48. package/dist/entrypoints/restoreInstance.d.ts +9 -0
  49. package/dist/error/LoadFormFailureError.d.ts +9 -0
  50. package/dist/error/MalformedInstanceDataError.d.ts +3 -0
  51. package/dist/error/RankMissingValueError.d.ts +3 -0
  52. package/dist/error/RankValueTypeError.d.ts +6 -0
  53. package/dist/error/SelectValueTypeError.d.ts +15 -0
  54. package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +22 -0
  55. package/dist/error/XFormsSpecViolationError.d.ts +2 -0
  56. package/dist/index.d.ts +2 -34
  57. package/dist/index.js +7274 -5840
  58. package/dist/index.js.map +1 -1
  59. package/dist/instance/Group.d.ts +7 -5
  60. package/dist/instance/InputControl.d.ts +9 -6
  61. package/dist/instance/ModelValue.d.ts +7 -4
  62. package/dist/instance/Note.d.ts +14 -25
  63. package/dist/instance/PrimaryInstance.d.ts +36 -8
  64. package/dist/instance/RangeControl.d.ts +35 -0
  65. package/dist/instance/RankControl.d.ts +41 -0
  66. package/dist/instance/Root.d.ts +8 -9
  67. package/dist/instance/SelectControl.d.ts +67 -0
  68. package/dist/instance/Subtree.d.ts +7 -5
  69. package/dist/instance/TriggerControl.d.ts +10 -22
  70. package/dist/instance/abstract/DescendantNode.d.ts +11 -3
  71. package/dist/instance/abstract/InstanceNode.d.ts +10 -5
  72. package/dist/instance/abstract/ValueNode.d.ts +7 -6
  73. package/dist/instance/children/DescendantNodeInitOptions.d.ts +32 -0
  74. package/dist/instance/{children.d.ts → children/buildChildren.d.ts} +1 -1
  75. package/dist/instance/children/childrenInitOptions.d.ts +9 -0
  76. package/dist/instance/children/normalizeChildInitOptions.d.ts +2 -0
  77. package/dist/instance/hierarchy.d.ts +9 -9
  78. package/dist/instance/input/InitialInstanceState.d.ts +13 -0
  79. package/dist/instance/input/InstanceAttachmentMap.d.ts +19 -0
  80. package/dist/instance/internal-api/InstanceConfig.d.ts +2 -9
  81. package/dist/instance/internal-api/InstanceValueContext.d.ts +10 -1
  82. package/dist/instance/internal-api/serialization/ClientReactiveSerializableInstance.d.ts +14 -0
  83. package/dist/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.d.ts +32 -0
  84. package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +18 -0
  85. package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +13 -0
  86. package/dist/instance/internal-api/serialization/ClientReactiveSerializableValueNode.d.ts +21 -0
  87. package/dist/instance/repeat/BaseRepeatRange.d.ts +11 -8
  88. package/dist/instance/repeat/RepeatInstance.d.ts +11 -7
  89. package/dist/instance/repeat/RepeatRangeControlled.d.ts +27 -3
  90. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +4 -3
  91. package/dist/instance/resource.d.ts +5 -1
  92. package/dist/instance/unsupported/UploadControl.d.ts +32 -4
  93. package/dist/integration/xpath/EngineXPathEvaluator.d.ts +2 -2
  94. package/dist/integration/xpath/adapter/kind.d.ts +4 -10
  95. package/dist/integration/xpath/adapter/names.d.ts +1 -11
  96. package/dist/integration/xpath/adapter/traversal.d.ts +10 -9
  97. package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +10 -4
  98. package/dist/integration/xpath/static-dom/StaticDocument.d.ts +13 -11
  99. package/dist/integration/xpath/static-dom/StaticElement.d.ts +25 -18
  100. package/dist/integration/xpath/static-dom/StaticNode.d.ts +1 -1
  101. package/dist/integration/xpath/static-dom/StaticParentNode.d.ts +13 -0
  102. package/dist/integration/xpath/static-dom/staticNodeName.d.ts +3 -0
  103. package/dist/lib/client-reactivity/instance-state/createNodeRangeInstanceState.d.ts +4 -0
  104. package/dist/lib/client-reactivity/instance-state/createParentNodeInstanceState.d.ts +4 -0
  105. package/dist/lib/client-reactivity/instance-state/createPrimaryInstanceState.d.ts +3 -0
  106. package/dist/lib/client-reactivity/instance-state/createRootInstanceState.d.ts +3 -0
  107. package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +6 -0
  108. package/dist/lib/client-reactivity/instance-state/createValueNodeInstanceState.d.ts +3 -0
  109. package/dist/lib/client-reactivity/instance-state/prepareInstancePayload.d.ts +8 -0
  110. package/dist/lib/codecs/Geopoint/Geopoint.d.ts +48 -0
  111. package/dist/lib/codecs/Geopoint/GeopointValueCodec.d.ts +5 -0
  112. package/dist/lib/codecs/NoteCodec.d.ts +8 -0
  113. package/dist/lib/codecs/RangeCodec.d.ts +8 -0
  114. package/dist/lib/codecs/TempUnsupportedControlCodec.d.ts +7 -0
  115. package/dist/lib/codecs/TriggerCodec.d.ts +7 -0
  116. package/dist/lib/codecs/ValueArrayCodec.d.ts +11 -0
  117. package/dist/lib/codecs/ValueCodec.d.ts +2 -2
  118. package/dist/lib/codecs/getNoteCodec.d.ts +3 -0
  119. package/dist/lib/codecs/getSelectCodec.d.ts +5 -0
  120. package/dist/lib/codecs/getSharedValueCodec.d.ts +3 -2
  121. package/dist/lib/codecs/items/BaseItemCodec.d.ts +9 -0
  122. package/dist/lib/codecs/items/MultipleValueItemCodec.d.ts +14 -0
  123. package/dist/lib/codecs/items/SingleValueItemCodec.d.ts +24 -0
  124. package/dist/lib/dom/query.d.ts +1 -2
  125. package/dist/lib/names/NamespaceDeclaration.d.ts +45 -0
  126. package/dist/lib/names/NamespaceDeclarationMap.d.ts +137 -0
  127. package/dist/lib/names/NamespaceURL.d.ts +30 -0
  128. package/dist/lib/names/QualifiedName.d.ts +113 -0
  129. package/dist/lib/names/UnprefixedXFormsName.d.ts +4 -0
  130. package/dist/lib/number-parsers.d.ts +2 -0
  131. package/dist/lib/reactivity/createInstanceValueState.d.ts +2 -27
  132. package/dist/lib/reactivity/createItemCollection.d.ts +21 -0
  133. package/dist/lib/xml-serialization.d.ts +11 -2
  134. package/dist/parse/XFormDOM.d.ts +1 -1
  135. package/dist/parse/body/BodyDefinition.d.ts +2 -2
  136. package/dist/parse/body/appearance/rangeAppearanceParser.d.ts +3 -0
  137. package/dist/parse/body/control/InputControlDefinition.d.ts +3 -0
  138. package/dist/parse/body/control/ItemDefinition.d.ts +14 -0
  139. package/dist/parse/body/control/ItemsetDefinition.d.ts +18 -0
  140. package/dist/parse/body/control/RangeControlDefinition.d.ts +31 -2
  141. package/dist/parse/body/control/RankControlDefinition.d.ts +7 -3
  142. package/dist/parse/body/control/{select/SelectDefinition.d.ts → SelectControlDefinition.d.ts} +9 -9
  143. package/dist/parse/expression/ItemsetNodesetExpression.d.ts +1 -1
  144. package/dist/parse/expression/ItemsetValueExpression.d.ts +1 -1
  145. package/dist/parse/model/BindDefinition.d.ts +3 -1
  146. package/dist/parse/model/BindPreloadDefinition.d.ts +42 -0
  147. package/dist/parse/model/DescendentNodeDefinition.d.ts +4 -13
  148. package/dist/parse/model/ItextTranslationsDefinition.d.ts +18 -0
  149. package/dist/parse/model/LeafNodeDefinition.d.ts +9 -7
  150. package/dist/parse/model/ModelDefinition.d.ts +9 -2
  151. package/dist/parse/model/NodeDefinition.d.ts +30 -45
  152. package/dist/parse/model/NoteNodeDefinition.d.ts +7 -5
  153. package/dist/parse/model/RangeNodeDefinition.d.ts +42 -0
  154. package/dist/parse/model/RepeatDefinition.d.ts +62 -0
  155. package/dist/parse/model/RootAttributeDefinition.d.ts +21 -0
  156. package/dist/parse/model/RootAttributeMap.d.ts +24 -0
  157. package/dist/parse/model/RootDefinition.d.ts +15 -14
  158. package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +15 -2
  159. package/dist/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.d.ts +5 -0
  160. package/dist/parse/model/SecondaryInstance/defineSecondaryInstance.d.ts +5 -0
  161. package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +1 -7
  162. package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +1 -1
  163. package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +1 -1
  164. package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +1 -1
  165. package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +1 -1
  166. package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +1 -1
  167. package/dist/parse/model/{FormSubmissionDefinition.d.ts → SubmissionDefinition.d.ts} +2 -2
  168. package/dist/parse/model/SubtreeDefinition.d.ts +9 -7
  169. package/dist/parse/model/nodeDefinitionMap.d.ts +5 -0
  170. package/dist/parse/shared/parseInstanceXML.d.ts +21 -0
  171. package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +4 -22
  172. package/dist/parse/text/ItemLabelDefinition.d.ts +1 -1
  173. package/dist/parse/text/ItemsetLabelDefinition.d.ts +2 -2
  174. package/dist/parse/text/abstract/TextElementDefinition.d.ts +1 -1
  175. package/dist/parse/xpath/semantic-analysis.d.ts +1 -3
  176. package/dist/solid.js +7247 -5813
  177. package/dist/solid.js.map +1 -1
  178. package/package.json +15 -12
  179. package/src/client/BaseNode.ts +9 -4
  180. package/src/client/BaseValueNode.ts +8 -4
  181. package/src/client/GroupNode.ts +1 -0
  182. package/src/client/InputNode.ts +38 -2
  183. package/src/client/ModelValueNode.ts +1 -0
  184. package/src/client/NoteNode.ts +43 -7
  185. package/src/client/RangeNode.ts +51 -0
  186. package/src/client/RankNode.ts +54 -0
  187. package/src/client/RootNode.ts +30 -16
  188. package/src/client/SelectNode.ts +53 -26
  189. package/src/client/SubtreeNode.ts +1 -0
  190. package/src/client/TriggerNode.ts +12 -6
  191. package/src/client/constants.ts +12 -14
  192. package/src/client/form/CreateFormInstance.ts +19 -0
  193. package/src/client/form/EditFormInstance.ts +93 -0
  194. package/src/client/form/FormInstance.ts +114 -0
  195. package/src/client/form/FormInstanceConfig.ts +18 -0
  196. package/src/client/form/FormResource.ts +1 -0
  197. package/src/client/form/LoadForm.ts +92 -0
  198. package/src/client/form/LoadFormResult.ts +103 -0
  199. package/src/client/form/RestoreFormInstance.ts +14 -0
  200. package/src/client/hierarchy.ts +7 -8
  201. package/src/client/index.ts +47 -29
  202. package/src/client/node-types.ts +3 -5
  203. package/src/client/repeat/BaseRepeatRangeNode.ts +3 -4
  204. package/src/client/repeat/RepeatInstanceNode.ts +4 -8
  205. package/src/client/repeat/RepeatRangeControlledNode.ts +2 -2
  206. package/src/client/repeat/RepeatRangeUncontrolledNode.ts +2 -2
  207. package/src/client/resources.ts +2 -2
  208. package/src/client/serialization/InstanceData.ts +16 -0
  209. package/src/client/serialization/InstanceFile.ts +9 -0
  210. package/src/client/serialization/InstancePayload.ts +126 -0
  211. package/src/client/serialization/InstancePayloadOptions.ts +28 -0
  212. package/src/client/serialization/InstanceState.ts +14 -0
  213. package/src/client/submission/{SubmissionDefinition.ts → SubmissionMeta.ts} +1 -1
  214. package/src/client/unsupported/UnsupportedControlNode.ts +2 -6
  215. package/src/entrypoints/FormInstance.ts +55 -0
  216. package/src/entrypoints/FormResult/BaseFormResult.ts +40 -0
  217. package/src/entrypoints/FormResult/BaseInstantiableFormResult.ts +109 -0
  218. package/src/entrypoints/FormResult/FormFailureResult.ts +44 -0
  219. package/src/entrypoints/FormResult/FormSuccessResult.ts +25 -0
  220. package/src/entrypoints/FormResult/FormWarningResult.ts +25 -0
  221. package/src/entrypoints/createInstance.ts +23 -0
  222. package/src/entrypoints/editInstance.ts +24 -0
  223. package/src/entrypoints/index.ts +4 -0
  224. package/src/entrypoints/loadForm.ts +154 -0
  225. package/src/entrypoints/restoreInstance.ts +27 -0
  226. package/src/error/LoadFormFailureError.ts +114 -0
  227. package/src/error/MalformedInstanceDataError.ts +3 -0
  228. package/src/error/RankMissingValueError.ts +5 -0
  229. package/src/error/RankValueTypeError.ts +13 -0
  230. package/src/error/SelectValueTypeError.ts +22 -0
  231. package/src/error/TemplatedNodeAttributeSerializationError.ts +24 -0
  232. package/src/error/XFormsSpecViolationError.ts +1 -0
  233. package/src/index.ts +2 -56
  234. package/src/instance/Group.ts +17 -15
  235. package/src/instance/InputControl.ts +58 -12
  236. package/src/instance/ModelValue.ts +19 -11
  237. package/src/instance/Note.ts +40 -64
  238. package/src/instance/PrimaryInstance.ts +70 -31
  239. package/src/instance/RangeControl.ts +119 -0
  240. package/src/instance/RankControl.ts +208 -0
  241. package/src/instance/Root.ts +21 -31
  242. package/src/instance/SelectControl.ts +228 -0
  243. package/src/instance/Subtree.ts +17 -15
  244. package/src/instance/TriggerControl.ts +50 -80
  245. package/src/instance/abstract/DescendantNode.ts +13 -8
  246. package/src/instance/abstract/InstanceNode.ts +19 -7
  247. package/src/instance/abstract/ValueNode.ts +14 -15
  248. package/src/instance/children/DescendantNodeInitOptions.ts +35 -0
  249. package/src/instance/children/buildChildren.ts +206 -0
  250. package/src/instance/children/childrenInitOptions.ts +117 -0
  251. package/src/instance/children/normalizeChildInitOptions.ts +332 -0
  252. package/src/instance/hierarchy.ts +21 -16
  253. package/src/instance/input/InitialInstanceState.ts +108 -0
  254. package/src/instance/input/InstanceAttachmentMap.ts +142 -0
  255. package/src/instance/internal-api/InstanceConfig.ts +3 -10
  256. package/src/instance/internal-api/InstanceValueContext.ts +11 -1
  257. package/src/instance/internal-api/serialization/ClientReactiveSerializableInstance.ts +20 -0
  258. package/src/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.ts +43 -0
  259. package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +26 -0
  260. package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +24 -0
  261. package/src/instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts +28 -0
  262. package/src/instance/repeat/BaseRepeatRange.ts +21 -24
  263. package/src/instance/repeat/RepeatInstance.ts +27 -19
  264. package/src/instance/repeat/RepeatRangeControlled.ts +90 -17
  265. package/src/instance/repeat/RepeatRangeUncontrolled.ts +10 -9
  266. package/src/instance/resource.ts +18 -2
  267. package/src/instance/unsupported/UploadControl.ts +116 -5
  268. package/src/integration/xpath/EngineXPathEvaluator.ts +2 -2
  269. package/src/integration/xpath/adapter/kind.ts +1 -28
  270. package/src/integration/xpath/adapter/names.ts +66 -17
  271. package/src/integration/xpath/adapter/traversal.ts +12 -11
  272. package/src/integration/xpath/static-dom/StaticAttribute.ts +16 -7
  273. package/src/integration/xpath/static-dom/StaticDocument.ts +17 -18
  274. package/src/integration/xpath/static-dom/StaticElement.ts +211 -52
  275. package/src/integration/xpath/static-dom/StaticNode.ts +1 -1
  276. package/src/integration/xpath/static-dom/StaticParentNode.ts +22 -0
  277. package/src/integration/xpath/static-dom/staticNodeName.ts +20 -0
  278. package/src/lib/client-reactivity/instance-state/createNodeRangeInstanceState.ts +17 -0
  279. package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +22 -0
  280. package/src/lib/client-reactivity/instance-state/createPrimaryInstanceState.ts +12 -0
  281. package/src/lib/client-reactivity/instance-state/createRootInstanceState.ts +19 -0
  282. package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +31 -0
  283. package/src/lib/client-reactivity/instance-state/createValueNodeInstanceState.ts +21 -0
  284. package/src/lib/client-reactivity/instance-state/prepareInstancePayload.ts +173 -0
  285. package/src/lib/codecs/Geopoint/Geopoint.ts +150 -0
  286. package/src/lib/codecs/Geopoint/GeopointValueCodec.ts +20 -0
  287. package/src/lib/codecs/NoteCodec.ts +32 -0
  288. package/src/lib/codecs/RangeCodec.ts +65 -0
  289. package/src/lib/codecs/TempUnsupportedControlCodec.ts +32 -0
  290. package/src/lib/codecs/TriggerCodec.ts +64 -0
  291. package/src/lib/codecs/ValueArrayCodec.ts +42 -0
  292. package/src/lib/codecs/ValueCodec.ts +2 -2
  293. package/src/lib/codecs/getNoteCodec.ts +27 -0
  294. package/src/lib/codecs/getSelectCodec.ts +27 -0
  295. package/src/lib/codecs/getSharedValueCodec.ts +5 -3
  296. package/src/lib/codecs/items/BaseItemCodec.ts +20 -0
  297. package/src/lib/codecs/items/MultipleValueItemCodec.ts +28 -0
  298. package/src/lib/codecs/items/SingleValueItemCodec.ts +67 -0
  299. package/src/lib/dom/query.ts +1 -2
  300. package/src/lib/names/NamespaceDeclaration.ts +106 -0
  301. package/src/lib/names/NamespaceDeclarationMap.ts +228 -0
  302. package/src/lib/names/NamespaceURL.ts +44 -0
  303. package/src/lib/names/QualifiedName.ts +170 -0
  304. package/src/lib/names/UnprefixedXFormsName.ts +12 -0
  305. package/src/lib/number-parsers.ts +25 -0
  306. package/src/lib/reactivity/createInstanceValueState.ts +69 -43
  307. package/src/lib/reactivity/{createSelectItems.ts → createItemCollection.ts} +41 -36
  308. package/src/lib/xml-serialization.ts +76 -9
  309. package/src/parse/XFormDOM.ts +141 -21
  310. package/src/parse/XFormDefinition.ts +1 -4
  311. package/src/parse/body/BodyDefinition.ts +4 -4
  312. package/src/parse/body/appearance/rangeAppearanceParser.ts +11 -0
  313. package/src/parse/body/control/InputControlDefinition.ts +9 -0
  314. package/src/parse/body/control/{select/ItemDefinition.ts → ItemDefinition.ts} +8 -6
  315. package/src/parse/body/control/{select/ItemsetDefinition.ts → ItemsetDefinition.ts} +11 -9
  316. package/src/parse/body/control/RangeControlDefinition.ts +91 -6
  317. package/src/parse/body/control/RankControlDefinition.ts +25 -7
  318. package/src/parse/body/control/{select/SelectDefinition.ts → SelectControlDefinition.ts} +9 -9
  319. package/src/parse/expression/ItemsetNodesetExpression.ts +1 -1
  320. package/src/parse/expression/ItemsetValueExpression.ts +1 -1
  321. package/src/parse/model/BindDefinition.ts +4 -0
  322. package/src/parse/model/BindPreloadDefinition.ts +100 -0
  323. package/src/parse/model/DescendentNodeDefinition.ts +7 -25
  324. package/src/parse/model/ItextTranslationsDefinition.ts +79 -0
  325. package/src/parse/model/LeafNodeDefinition.ts +13 -8
  326. package/src/parse/model/ModelDefinition.ts +36 -3
  327. package/src/parse/model/NodeDefinition.ts +38 -85
  328. package/src/parse/model/NoteNodeDefinition.ts +12 -10
  329. package/src/parse/model/RangeNodeDefinition.ts +119 -0
  330. package/src/parse/model/RepeatDefinition.ts +382 -0
  331. package/src/parse/model/RootAttributeDefinition.ts +44 -0
  332. package/src/parse/model/RootAttributeMap.ts +49 -0
  333. package/src/parse/model/RootDefinition.ts +42 -43
  334. package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +23 -2
  335. package/src/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.ts +14 -0
  336. package/src/parse/model/SecondaryInstance/defineSecondaryInstance.ts +32 -0
  337. package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +3 -24
  338. package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +33 -86
  339. package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +64 -136
  340. package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +9 -7
  341. package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +1 -1
  342. package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +7 -7
  343. package/src/parse/model/{FormSubmissionDefinition.ts → SubmissionDefinition.ts} +2 -2
  344. package/src/parse/model/SubtreeDefinition.ts +15 -16
  345. package/src/parse/model/nodeDefinitionMap.ts +34 -0
  346. package/src/parse/shared/parseInstanceXML.ts +79 -0
  347. package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +46 -131
  348. package/src/parse/text/ItemLabelDefinition.ts +1 -1
  349. package/src/parse/text/ItemsetLabelDefinition.ts +2 -2
  350. package/src/parse/text/abstract/TextElementDefinition.ts +1 -1
  351. package/src/parse/xpath/semantic-analysis.ts +4 -3
  352. package/dist/client/EngineConfig.d.ts +0 -79
  353. package/dist/client/submission/SubmissionData.d.ts +0 -7
  354. package/dist/client/submission/SubmissionInstanceFile.d.ts +0 -6
  355. package/dist/client/submission/SubmissionOptions.d.ts +0 -23
  356. package/dist/client/submission/SubmissionResult.d.ts +0 -91
  357. package/dist/client/submission/SubmissionState.d.ts +0 -12
  358. package/dist/client/unsupported/RangeNode.d.ts +0 -9
  359. package/dist/client/unsupported/RankNode.d.ts +0 -9
  360. package/dist/instance/SelectField.d.ts +0 -58
  361. package/dist/instance/abstract/UnsupportedControl.d.ts +0 -53
  362. package/dist/instance/index.d.ts +0 -8
  363. package/dist/instance/internal-api/ValueContext.d.ts +0 -23
  364. package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +0 -14
  365. package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +0 -31
  366. package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +0 -18
  367. package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +0 -17
  368. package/dist/instance/unsupported/RangeControl.d.ts +0 -6
  369. package/dist/instance/unsupported/RankControl.d.ts +0 -6
  370. package/dist/integration/xpath/static-dom/StaticNamedNode.d.ts +0 -17
  371. package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +0 -3
  372. package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +0 -3
  373. package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +0 -4
  374. package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +0 -4
  375. package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +0 -3
  376. package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +0 -8
  377. package/dist/lib/reactivity/createSelectItems.d.ts +0 -16
  378. package/dist/lib/reactivity/createValueState.d.ts +0 -40
  379. package/dist/parse/body/control/select/ItemDefinition.d.ts +0 -13
  380. package/dist/parse/body/control/select/ItemsetDefinition.d.ts +0 -17
  381. package/dist/parse/body/control/select/ItemsetNodesetContext.d.ts +0 -9
  382. package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +0 -4
  383. package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +0 -8
  384. package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +0 -8
  385. package/dist/parse/model/RepeatInstanceDefinition.d.ts +0 -14
  386. package/dist/parse/model/RepeatRangeDefinition.d.ts +0 -29
  387. package/dist/parse/model/RepeatTemplateDefinition.d.ts +0 -28
  388. package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +0 -4
  389. package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +0 -7
  390. package/src/client/EngineConfig.ts +0 -84
  391. package/src/client/submission/SubmissionData.ts +0 -12
  392. package/src/client/submission/SubmissionInstanceFile.ts +0 -9
  393. package/src/client/submission/SubmissionOptions.ts +0 -28
  394. package/src/client/submission/SubmissionResult.ts +0 -124
  395. package/src/client/submission/SubmissionState.ts +0 -14
  396. package/src/client/unsupported/RangeNode.ts +0 -14
  397. package/src/client/unsupported/RankNode.ts +0 -14
  398. package/src/instance/SelectField.ts +0 -263
  399. package/src/instance/abstract/UnsupportedControl.ts +0 -174
  400. package/src/instance/children.ts +0 -158
  401. package/src/instance/index.ts +0 -55
  402. package/src/instance/internal-api/ValueContext.ts +0 -28
  403. package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +0 -20
  404. package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +0 -42
  405. package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +0 -25
  406. package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +0 -23
  407. package/src/instance/unsupported/RangeControl.ts +0 -9
  408. package/src/instance/unsupported/RankControl.ts +0 -9
  409. package/src/integration/xpath/static-dom/StaticNamedNode.ts +0 -45
  410. package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +0 -12
  411. package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +0 -20
  412. package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +0 -17
  413. package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +0 -22
  414. package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +0 -21
  415. package/src/lib/client-reactivity/submission/prepareSubmission.ts +0 -172
  416. package/src/lib/reactivity/createValueState.ts +0 -200
  417. package/src/parse/body/control/select/ItemsetNodesetContext.ts +0 -21
  418. package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +0 -4
  419. package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +0 -41
  420. package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +0 -31
  421. package/src/parse/model/RepeatInstanceDefinition.ts +0 -34
  422. package/src/parse/model/RepeatRangeDefinition.ts +0 -94
  423. package/src/parse/model/RepeatTemplateDefinition.ts +0 -145
  424. package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +0 -4
  425. package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +0 -12
@@ -1,17 +1,7 @@
1
1
  import type { XPathNodeKind } from '@getodk/xpath';
2
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';
3
+ import type { AnyChildNode, AnyNode, AnyParentNode } from '../../../instance/hierarchy.ts';
10
4
  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
5
  import type { StaticAttribute } from '../static-dom/StaticAttribute.ts';
16
6
  import type { StaticDocument } from '../static-dom/StaticDocument.ts';
17
7
  import type { StaticElement } from '../static-dom/StaticElement.ts';
@@ -35,26 +25,14 @@ export type PrimaryInstanceXPathChildNode =
35
25
  | PrimaryInstanceXPathElement
36
26
  | PrimaryInstanceXPathComment;
37
27
 
38
- // prettier-ignore
39
- export type PrimaryInstanceXPathValueElement<Value> =
40
- & AnyValueNode
41
- & ValueContext<Value>
42
- & XFormsXPathElement;
43
-
44
28
  // prettier-ignore
45
29
  export type EngineXPathDocument =
46
- // eslint-disable-next-line @typescript-eslint/sort-type-constituents
47
30
  | PrimaryInstance
48
- | ItextTranslationDefinition
49
- | SecondaryInstanceDefinition
50
31
  | StaticDocument;
51
32
 
52
33
  // prettier-ignore
53
34
  export type EngineXPathElement =
54
- // eslint-disable-next-line @typescript-eslint/sort-type-constituents
55
35
  | PrimaryInstanceXPathElement
56
- | ItextTranslationRootDefinition
57
- | SecondaryInstanceRootDefinition
58
36
  | StaticElement;
59
37
 
60
38
  // prettier-ignore
@@ -83,12 +61,7 @@ type PrimaryInstanceXPathParentNode = Extract<AnyParentNode, XPathAdapterParentN
83
61
 
84
62
  // prettier-ignore
85
63
  export type EngineXPathParentNode =
86
- // eslint-disable-next-line @typescript-eslint/sort-type-constituents
87
64
  | PrimaryInstanceXPathParentNode
88
- | ItextTranslationDefinition
89
- | SecondaryInstanceDefinition
90
- | ItextTranslationRootDefinition
91
- | SecondaryInstanceRootDefinition
92
65
  | StaticDocument
93
66
  | StaticElement;
94
67
 
@@ -15,49 +15,54 @@ import {
15
15
  XHTML_NAMESPACE_URI,
16
16
  } from '@getodk/common/constants/xmlns.ts';
17
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';
18
+ import type { AnyStaticNode } from '../static-dom/StaticNode.ts';
20
19
  import type { EngineXPathNode } from './kind.ts';
21
- import type { getNamespaceDeclarations } from './traversal.ts';
22
20
 
23
21
  export const getEngineXPathNodeNamespaceURI = (node: EngineXPathNode): string | null => {
24
22
  switch (node.nodeType) {
25
23
  case 'primary-instance':
24
+ case 'static-document':
26
25
  case 'static-text':
26
+ case 'repeat-range:controlled':
27
+ case 'repeat-range:uncontrolled':
27
28
  return null;
28
29
 
29
30
  case 'static-attribute':
30
31
  case 'static-element':
31
- return node.namespaceURI;
32
+ return node.qualifiedName.namespaceURI?.href ?? null;
32
33
 
33
34
  default:
34
- return XFORMS_NAMESPACE_URI;
35
+ return node.definition.qualifiedName.namespaceURI?.href ?? null;
35
36
  }
36
37
  };
37
38
 
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
39
  export const getEngineXPathNodeQualifiedName = (node: EngineXPathNode): string => {
46
- return getEngineXPathNodeLocalName(node);
40
+ switch (node.nodeType) {
41
+ case 'static-attribute':
42
+ case 'static-element':
43
+ return node.qualifiedName.getPrefixedName();
44
+
45
+ case 'static-document':
46
+ case 'static-text':
47
+ return '';
48
+
49
+ default:
50
+ return node.definition.qualifiedName.getPrefixedName();
51
+ }
47
52
  };
48
53
 
49
54
  export const getEngineXPathNodeLocalName = (node: EngineXPathNode): string => {
50
55
  switch (node.nodeType) {
51
56
  case 'static-attribute':
52
57
  case 'static-element':
53
- return node.localName;
58
+ return node.qualifiedName.localName;
54
59
 
55
60
  case 'static-document':
56
61
  case 'static-text':
57
62
  return '';
58
63
 
59
64
  default:
60
- return node.definition.nodeName;
65
+ return node.definition.qualifiedName.localName;
61
66
  }
62
67
  };
63
68
 
@@ -65,9 +70,23 @@ export const getEngineProcessingInstructionName =
65
70
  XPathFunctionalityNotSupportedError.createStubImplementation('processing-instruction');
66
71
 
67
72
  /**
68
- * @todo @see {@link getNamespaceDeclarations}
73
+ * @todo in most cases we should not have **custom** namespace resolution from a
74
+ * static node (e.g. external secondary instance, itext translation) context.
75
+ * The main exception to that would be _XML external secondary instances_, which
76
+ * of course can declare arbitrary namespaces on any arbitrary subtree, just
77
+ * like a form definition's XML. In all other cases, we'd want to resolve a
78
+ * prefix here from the _primary instance_ context. However, we don't (yet) have
79
+ * access to the primary instance context from a static node. So we currently
80
+ * fall back to the previous (incomplete/potentially wrong) default mapping.
81
+ *
82
+ * Note that this is relatively safe for the general case, and only potentially
83
+ * wrong for:
84
+ *
85
+ * 1. Forms authored as XML, with arbitrary/non-default namespace declarations
86
+ * 2. XML external secondary instances, also with arbitrary/non-default
87
+ * namespace declarations
69
88
  */
70
- export const resolveEngineXPathNodeNamespaceURI = (_: EngineXPathNode, prefix: string | null) => {
89
+ const resolveNamespaceURIFromStaticNodeContext = (_: AnyStaticNode, prefix: string | null) => {
71
90
  switch (prefix) {
72
91
  case null:
73
92
  return XFORMS_NAMESPACE_URI;
@@ -97,3 +116,33 @@ export const resolveEngineXPathNodeNamespaceURI = (_: EngineXPathNode, prefix: s
97
116
  return null;
98
117
  }
99
118
  };
119
+
120
+ export const resolveEngineXPathNodeNamespaceURI = (
121
+ node: EngineXPathNode,
122
+ prefix: string | null
123
+ ): string | null => {
124
+ switch (node.nodeType) {
125
+ case 'static-attribute':
126
+ case 'static-document':
127
+ case 'static-element':
128
+ case 'static-text':
129
+ return resolveNamespaceURIFromStaticNodeContext(node, prefix);
130
+
131
+ case 'group':
132
+ case 'input':
133
+ case 'model-value':
134
+ case 'note':
135
+ case 'primary-instance':
136
+ case 'range':
137
+ case 'rank':
138
+ case 'repeat-instance':
139
+ case 'repeat-range:controlled':
140
+ case 'repeat-range:uncontrolled':
141
+ case 'root':
142
+ case 'select':
143
+ case 'subtree':
144
+ case 'trigger':
145
+ case 'upload':
146
+ return node.definition.namespaceDeclarations.get(prefix)?.declaredURI?.href ?? null;
147
+ }
148
+ };
@@ -2,7 +2,7 @@ import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
2
2
  import { ErrorProductionDesignPendingError } from '../../../error/ErrorProductionDesignPendingError.ts';
3
3
  import { XPathFunctionalityPendingError } from '../../../error/XPathFunctionalityPendingError.ts';
4
4
  import type { AnyNode } from '../../../instance/hierarchy.ts';
5
- import type { AnyStaticNode, StaticParentNode } from '../static-dom/StaticNode.ts';
5
+ import type { AnyStaticNode, StaticNodeParent } from '../static-dom/StaticNode.ts';
6
6
  import type {
7
7
  EngineXPathAttribute,
8
8
  EngineXPathDocument,
@@ -27,16 +27,17 @@ export const getEngineXPathAttributes = (node: EngineXPathNode): Iterable<Engine
27
27
  };
28
28
 
29
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).
30
+ * @todo We've now laid most of the groundwork necessary to implement this
31
+ * properly. At time of writing it has still been deferred because:
38
32
  *
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.
33
+ * 1. The scope of changes enabling it is already a fairly large yak shave.
34
+ * 2. It is only used to support XPath LocationPath Steps whose AxisName is
35
+ * `namespace`. If we _ever_ support this, it would probably be for extremely
36
+ * niche use cases!
37
+ *
38
+ * @todo Since we've consciously deferred implementing this (twice now!), should
39
+ * it throw? It might be nice to be alerted if the assumptions in point 2 above
40
+ * are somehow wrong (or become wrong).
40
41
  */
41
42
  export const getNamespaceDeclarations = (): Iterable<never> => [];
42
43
 
@@ -167,7 +168,7 @@ const primaryInstanceElementContains = (ancestor: AnyNode, other: AnyNode): bool
167
168
  return primaryInstanceElementContains(ancestor, parent);
168
169
  };
169
170
 
170
- const staticParentNodeContains = (ancestor: StaticParentNode, other: AnyStaticNode): boolean => {
171
+ const staticParentNodeContains = (ancestor: StaticNodeParent, other: AnyStaticNode): boolean => {
171
172
  if (ancestor === other) {
172
173
  return false;
173
174
  }
@@ -1,28 +1,37 @@
1
1
  import { XPathNodeKindKey } from '@getodk/xpath';
2
+ import { QualifiedName } from '../../../lib/names/QualifiedName.ts';
2
3
  import type { XFormsXPathAttribute } from '../adapter/XFormsXPathNode.ts';
4
+ import type { StaticDocument } from './StaticDocument.ts';
3
5
  import type { StaticElement } from './StaticElement.ts';
4
- import type { StaticNamedNodeOptions } from './StaticNamedNode.ts';
5
- import { StaticNamedNode } from './StaticNamedNode.ts';
6
+ import { StaticNode } from './StaticNode.ts';
7
+ import { staticNodeName, type StaticNodeNameSource } from './staticNodeName.ts';
6
8
 
7
- interface StaticAttributeOptions extends StaticNamedNodeOptions {
9
+ export interface StaticAttributeOptions {
10
+ readonly name: StaticNodeNameSource;
8
11
  readonly value: string;
9
12
  }
10
13
 
11
- export class StaticAttribute extends StaticNamedNode<'attribute'> implements XFormsXPathAttribute {
14
+ export class StaticAttribute extends StaticNode<'attribute'> implements XFormsXPathAttribute {
12
15
  readonly [XPathNodeKindKey] = 'attribute';
13
16
  readonly nodeType = 'static-attribute';
17
+ readonly rootDocument: StaticDocument;
14
18
  readonly root: StaticElement;
19
+ readonly qualifiedName: QualifiedName;
20
+ readonly nodeset: string;
15
21
  readonly attributes = [] as const;
16
22
  readonly children = null;
17
- override readonly value: string;
23
+ readonly value: string;
18
24
 
19
25
  constructor(
20
- override readonly parent: StaticElement,
26
+ readonly parent: StaticElement,
21
27
  options: StaticAttributeOptions
22
28
  ) {
23
- super(parent, options);
29
+ super();
24
30
 
31
+ this.rootDocument = parent.rootDocument;
25
32
  this.root = parent.root;
33
+ this.qualifiedName = staticNodeName(options.name);
34
+ this.nodeset = `${parent.nodeset}/@${this.qualifiedName.getPrefixedName()}`;
26
35
  this.value = options.value;
27
36
  }
28
37
 
@@ -1,34 +1,33 @@
1
- import { XPathNodeKindKey } from '@getodk/xpath';
2
1
  import type { XFormsXPathDocument } from '../adapter/XFormsXPathNode.ts';
2
+ import type { StaticElementOptions } from './StaticElement.ts';
3
3
  import { StaticElement } from './StaticElement.ts';
4
- import { StaticNode } from './StaticNode.ts';
4
+ import { StaticParentNode } from './StaticParentNode.ts';
5
5
 
6
- export type StaticDocumentRootFactory<T extends StaticDocument, Root extends StaticElement> = (
7
- staticDocument: T
8
- ) => Root;
6
+ interface StaticDocumentOptions {
7
+ readonly documentRoot: StaticElementOptions;
8
+ readonly nodesetPrefix?: string;
9
+ }
9
10
 
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';
11
+ export class StaticDocument extends StaticParentNode<'document'> implements XFormsXPathDocument {
16
12
  readonly rootDocument: StaticDocument;
17
- readonly root: DocumentRoot;
18
- readonly isXFormsNamespace: boolean;
13
+ readonly root: StaticElement;
19
14
  readonly parent = null;
20
- readonly children: readonly [root: DocumentRoot];
15
+ readonly nodeset: string;
16
+ readonly children: readonly [root: StaticElement];
17
+ readonly childElements: readonly [root: StaticElement];
21
18
 
22
- constructor(rootFactory: StaticDocumentRootFactory<StaticDocument<DocumentRoot>, DocumentRoot>) {
23
- super();
19
+ constructor(options: StaticDocumentOptions) {
20
+ super('document');
24
21
 
22
+ this.nodeset = options.nodesetPrefix ?? '/';
25
23
  this.rootDocument = this;
26
24
 
27
- const root = rootFactory(this);
25
+ const { documentRoot } = options;
26
+ const root = new StaticElement(this, documentRoot);
28
27
 
29
28
  this.root = root;
30
- this.isXFormsNamespace = root.isXFormsNamespace;
31
29
  this.children = [root];
30
+ this.childElements = this.children;
32
31
  }
33
32
 
34
33
  // XFormsXPathDocument
@@ -1,68 +1,218 @@
1
- import { XFORMS_KNOWN_ATTRIBUTE, XFORMS_LOCAL_NAME, XPathNodeKindKey } from '@getodk/xpath';
1
+ import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
2
+ import { ErrorProductionDesignPendingError } from '../../../error/ErrorProductionDesignPendingError.ts';
3
+ import type { QualifiedNameSource } from '../../../lib/names/QualifiedName.ts';
4
+ import { QualifiedName } from '../../../lib/names/QualifiedName.ts';
2
5
  import type { EngineDOMAdapter } from '../adapter/engineDOMAdapter.ts';
3
6
  import type { XFormsXPathElement } from '../adapter/XFormsXPathNode.ts';
7
+ import type { StaticAttributeOptions } from './StaticAttribute.ts';
4
8
  import { StaticAttribute } from './StaticAttribute.ts';
5
- import type { StaticNamedNodeOptions } from './StaticNamedNode.ts';
6
- import { StaticNamedNode } from './StaticNamedNode.ts';
7
- import type { StaticChildNode, StaticParentNode } from './StaticNode.ts';
8
-
9
- export type StaticElementAttributesFactory = (element: StaticElement) => readonly StaticAttribute[];
10
-
11
- export type StaticElementChildNodesFactory = (element: StaticElement) => readonly StaticChildNode[];
12
-
13
- export interface StaticElementOptions extends StaticNamedNodeOptions {}
14
-
15
- type StaticElementKnownAttributeValue<
16
- T extends StaticElement,
17
- LocalName extends string,
18
- > = T extends { readonly [XFORMS_KNOWN_ATTRIBUTE]: LocalName } ? string : string | null;
19
-
20
- type AssertStaticElementKnownAttributeValue = <T extends StaticElement, LocalName extends string>(
21
- element: T,
22
- localName: LocalName,
23
- value: string | null
24
- ) => asserts value is StaticElementKnownAttributeValue<T, LocalName>;
25
-
26
- const assertStaticElementKnownAttributeValue: AssertStaticElementKnownAttributeValue = (
27
- element,
28
- localName,
29
- value
30
- ) => {
31
- if (localName === element[XFORMS_KNOWN_ATTRIBUTE] && value == null) {
32
- throw new Error(`Expected attribute: ${element[XFORMS_KNOWN_ATTRIBUTE]}`);
9
+ import type { StaticDocument } from './StaticDocument.ts';
10
+ import type { StaticChildNode } from './StaticNode.ts';
11
+ import { staticNodeName } from './staticNodeName.ts';
12
+ import { StaticParentNode } from './StaticParentNode.ts';
13
+ import { StaticText } from './StaticText.ts';
14
+
15
+ // prettier-ignore
16
+ export type StaticElementChildOption =
17
+ | StaticElementOptions
18
+ | string;
19
+
20
+ export interface StaticElementOptions {
21
+ readonly name: QualifiedNameSource | string;
22
+ readonly attributes?: readonly StaticAttributeOptions[];
23
+ readonly children?: readonly StaticElementChildOption[];
24
+ }
25
+
26
+ interface StaticElementChildrenResult {
27
+ readonly children: readonly StaticChildNode[];
28
+ readonly childElements: readonly StaticElement[];
29
+ readonly leafValue: string | null;
30
+ }
31
+
32
+ const leafElementChildrenResult = (
33
+ parent: StaticElement,
34
+ leafValue: string
35
+ ): StaticElementChildrenResult => {
36
+ const child = new StaticText(parent, leafValue);
37
+
38
+ return {
39
+ children: [child],
40
+ childElements: [],
41
+ leafValue: leafValue,
42
+ };
43
+ };
44
+
45
+ const blankLeafElementChildrenResult = (parent: StaticElement): StaticElementChildrenResult => {
46
+ return leafElementChildrenResult(parent, '');
47
+ };
48
+
49
+ /**
50
+ * Builds several "views" into a {@link StaticElement}'s children as:
51
+ *
52
+ * - An array of all of its {@link StaticChildNode | child nodes}
53
+ * - A subset array of only its {@link StaticElement | child elements}
54
+ * - A {@link StaticElementChildrenResult.leafValue | "leaf value"} which is
55
+ * populated with the text value of a {@link StaticText | text node} if **and
56
+ * only if** that text node is the element's sole child node (which is in turn
57
+ * used to identify which _elements_ are {@link StaticLeafElement | leaf}
58
+ * nodes)
59
+ *
60
+ * @todo this is awkwardly named and awkward to describe! It's done this way for
61
+ * efficiency (which makes a substantial difference for large forms), at the
62
+ * expense of code clarity.
63
+ *
64
+ * @todo Handle comment nodes (1): we have discussed the possibility of using
65
+ * comments as a placeholder for omitted non-relevant repeat instances, as an
66
+ * aide to recreating them in restore/edit modes.
67
+ *
68
+ * @todo Handle comment nodes (2): comments are currently _effectively implied_
69
+ * in the function-body comment about a homogenous sequence of 2+ strings, i.e.
70
+ * in a structure like `<foo>bar<!-- bat -->quux</foo>`. If we handle comment
71
+ * nodes, the only way we'd encounter that scenario is if we're parsing a
72
+ * `StaticElement` from a DOM `Element` (or some other source with similar
73
+ * semantics) where its child nodes have been manipulated into that state. As
74
+ * such, if we do handle comments, that comment should likely be removed.
75
+ */
76
+ const buildStaticElementChildren = (
77
+ parent: StaticElement,
78
+ options: StaticElementOptions
79
+ ): StaticElementChildrenResult => {
80
+ const children = Array<StaticChildNode>();
81
+ const childElements = Array<StaticElement>();
82
+ const childOptions = options.children ?? [''];
83
+
84
+ // No children: blank value
85
+ if (childOptions.length === 0) {
86
+ return {
87
+ children,
88
+ childElements,
89
+ leafValue: '',
90
+ };
91
+ }
92
+
93
+ const [head, ...tail] = childOptions;
94
+
95
+ if (tail.length === 0) {
96
+ // - If no child options are specified, default to a single empty/blank
97
+ // `StaticText` child node, and assign its value
98
+ if (head == null) {
99
+ return blankLeafElementChildrenResult(parent);
100
+ }
101
+
102
+ // - If exactly one child option is specified, and it is a string, create
103
+ // `StaticText` child and assign its value
104
+ if (typeof head === 'string') {
105
+ return leafElementChildrenResult(parent, head);
106
+ }
107
+ }
108
+
109
+ // If 2+ child options, for each:
110
+ //
111
+ // - Populate `children` (and `childElements`, as appopriate)
112
+ // - Do not populate `value`. For cases which need an arbitrary
113
+ // `StaticElement`'s text value (i.e. `XPath`, perhaps eventually some
114
+ // serialization use cases), it will be computed recursively as needed.
115
+ //
116
+ // Note: in theory, we may encounter a homogenous sequence of 2+ strings! In
117
+ // theory we should normalize those into a single string.
118
+ if (typeof head === 'string' && tail.length === 0) {
119
+ const child = new StaticText(parent, head);
120
+
121
+ children.push(child);
122
+
123
+ return {
124
+ children,
125
+ childElements,
126
+ leafValue: child.value,
127
+ };
128
+ }
129
+
130
+ for (const item of childOptions) {
131
+ switch (typeof item) {
132
+ case 'string':
133
+ children.push(new StaticText(parent, item));
134
+ break;
135
+
136
+ case 'object': {
137
+ const childElement = new StaticElement(parent, item);
138
+
139
+ children.push(childElement);
140
+ childElements.push(childElement);
141
+
142
+ break;
143
+ }
144
+
145
+ default:
146
+ throw new UnreachableError(item);
147
+ }
33
148
  }
149
+
150
+ return {
151
+ children,
152
+ childElements,
153
+ leafValue: null,
154
+ };
34
155
  };
35
156
 
36
- export class StaticElement<Parent extends StaticParentNode = StaticParentNode>
37
- extends StaticNamedNode<'element'>
38
- implements XFormsXPathElement
39
- {
40
- readonly [XFORMS_LOCAL_NAME]?: string;
41
- readonly [XFORMS_KNOWN_ATTRIBUTE]?: string;
157
+ export class StaticElement extends StaticParentNode<'element'> implements XFormsXPathElement {
158
+ private computedValue: string | null;
42
159
 
43
- readonly [XPathNodeKindKey] = 'element';
44
- readonly nodeType = 'static-element';
160
+ readonly rootDocument: StaticDocument;
45
161
  readonly root: StaticElement;
162
+ readonly qualifiedName: QualifiedName;
163
+ readonly nodeset: string;
46
164
  readonly attributes: readonly StaticAttribute[];
47
165
  readonly children: readonly StaticChildNode[];
166
+ readonly childElements: readonly StaticElement[];
167
+ readonly value: string | null;
48
168
 
49
169
  constructor(
50
- parent: Parent,
51
- attributesFactory: StaticElementAttributesFactory,
52
- childNodesFactory: StaticElementChildNodesFactory,
170
+ readonly parent: StaticDocument | StaticElement,
53
171
  options: StaticElementOptions
54
172
  ) {
55
- super(parent, options);
173
+ super('element');
174
+
175
+ const { rootDocument } = parent;
176
+ let nodesetPrefix = parent.nodeset;
177
+
178
+ this.rootDocument = rootDocument;
56
179
 
57
180
  // Account for the fact that we may be constructing the document root!
58
- if (parent === this.rootDocument) {
181
+ if (parent === rootDocument) {
59
182
  this.root = this;
183
+
184
+ // Avoid nodeset like `//foo` when `/foo` is expected/intended
185
+ if (nodesetPrefix === '/') {
186
+ nodesetPrefix = '';
187
+ }
60
188
  } else {
61
189
  this.root = parent.root;
62
190
  }
63
191
 
64
- this.attributes = attributesFactory(this);
65
- this.children = childNodesFactory(this);
192
+ const { name, attributes = [] } = options;
193
+
194
+ this.qualifiedName = staticNodeName(name);
195
+ this.nodeset = `${nodesetPrefix}/${this.qualifiedName.getPrefixedName()}`;
196
+ this.attributes = attributes.map((attrOptions) => {
197
+ return new StaticAttribute(this, attrOptions);
198
+ });
199
+
200
+ const { children, childElements, leafValue } = buildStaticElementChildren(this, options);
201
+
202
+ this.children = children;
203
+ this.childElements = childElements;
204
+ this.computedValue = leafValue;
205
+ this.value = leafValue;
206
+ }
207
+
208
+ isLeafElement(): this is StaticLeafElement {
209
+ return this.value != null;
210
+ }
211
+
212
+ assertLeafElement(): asserts this is StaticLeafElement {
213
+ if (!this.isLeafElement()) {
214
+ throw new ErrorProductionDesignPendingError();
215
+ }
66
216
  }
67
217
 
68
218
  /**
@@ -73,7 +223,7 @@ export class StaticElement<Parent extends StaticParentNode = StaticParentNode>
73
223
  protected getAttributeNode(localName: string): StaticAttribute | null {
74
224
  return (
75
225
  this.attributes.find((attribute) => {
76
- return attribute.localName === localName;
226
+ return attribute.qualifiedName.localName === localName;
77
227
  }) ?? null
78
228
  );
79
229
  }
@@ -87,20 +237,29 @@ export class StaticElement<Parent extends StaticParentNode = StaticParentNode>
87
237
  * up. (This was put off because the types are already plenty complex as it
88
238
  * is.)
89
239
  */
90
- getAttributeValue<This extends StaticElement, LocalName extends string>(
91
- this: This,
92
- localName: LocalName
93
- ): StaticElementKnownAttributeValue<This, LocalName> {
240
+ getAttributeValue(localName: string): string | null {
94
241
  const attribute = this.getAttributeNode(localName);
95
242
  const value = attribute?.value ?? null;
96
243
 
97
- assertStaticElementKnownAttributeValue(this, localName, value);
98
-
99
244
  return value;
100
245
  }
101
246
 
102
247
  // XFormsXPathElement
103
248
  getXPathValue(): string {
104
- return this.children.map((child) => child.getXPathValue()).join('');
249
+ const { computedValue } = this;
250
+
251
+ if (computedValue != null) {
252
+ return computedValue;
253
+ }
254
+
255
+ const result = this.children.map((child) => child.getXPathValue()).join('');
256
+
257
+ this.computedValue = result;
258
+
259
+ return result;
105
260
  }
106
261
  }
262
+
263
+ export interface StaticLeafElement extends StaticElement {
264
+ readonly value: string;
265
+ }
@@ -58,7 +58,7 @@ export type AnyStaticNode =
58
58
  | StaticText;
59
59
 
60
60
  // prettier-ignore
61
- export type StaticParentNode =
61
+ export type StaticNodeParent =
62
62
  | StaticDocument
63
63
  | StaticElement;
64
64
 
@@ -0,0 +1,22 @@
1
+ import { XPathNodeKindKey } from '@getodk/xpath';
2
+ import type { StaticElement } from './StaticElement.ts';
3
+ import { StaticNode, type StaticChildNode } from './StaticNode.ts';
4
+
5
+ type StaticParentNodeKind = 'document' | 'element';
6
+
7
+ type StaticParentNodeType<Kind extends StaticParentNodeKind> = `static-${Kind}`;
8
+
9
+ export abstract class StaticParentNode<Kind extends StaticParentNodeKind> extends StaticNode<Kind> {
10
+ abstract override readonly children: readonly StaticChildNode[];
11
+ abstract readonly childElements: readonly StaticElement[];
12
+
13
+ readonly [XPathNodeKindKey]: Kind;
14
+ readonly nodeType: StaticParentNodeType<Kind>;
15
+
16
+ constructor(kind: Kind) {
17
+ super();
18
+
19
+ this[XPathNodeKindKey] = kind;
20
+ this.nodeType = `static-${kind}`;
21
+ }
22
+ }