@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
@@ -0,0 +1,170 @@
1
+ import type { XPathDOMAdapter } from '@getodk/xpath';
2
+ import { NamespaceURL } from './NamespaceURL.ts';
3
+
4
+ export type NamespaceURI = NamespaceURL | null;
5
+ export type QualifiedNamePrefix = string | null;
6
+
7
+ export interface NamespaceQualifiedNameSource {
8
+ readonly namespaceURI: NamespaceURI | string;
9
+ readonly localName: string;
10
+
11
+ /**
12
+ * Note that this property is intentionally optional as one of the
13
+ * {@link QualifiedNameSource | QualifiedName source input}, and its absence
14
+ * is treated differently from an explicitly assigned `null` value.
15
+ *
16
+ * @see {@link SourcePrefixUnspecified}, {@link DeferredPrefix}
17
+ */
18
+ readonly prefix?: QualifiedNamePrefix;
19
+ }
20
+
21
+ const SOURCE_PREFIX_UNSPECIFIED = Symbol('SOURCE_PREFIX_UNSPECIFIED');
22
+
23
+ /**
24
+ * May be used as a placeholder for a {@link QualifiedName.prefix}, where the
25
+ * actual prefix may not be known at definition time.
26
+ *
27
+ * Example: parsing non-XML sources into an XML-like tree, e.g. for XPath
28
+ * evaluation; in which case, we may not need to resolve a prefix for the name
29
+ * until such a node is serialized as XML, if it ever is.
30
+ */
31
+ type SourcePrefixUnspecified = typeof SOURCE_PREFIX_UNSPECIFIED;
32
+
33
+ /**
34
+ * Represents a {@link QualifiedName.prefix} whose resolution may be deferred,
35
+ * e.g. until all requisite parsing is complete and/or until XML serialization
36
+ * requires use of a prefix to represent the corresponding
37
+ * {@link QualifiedName.namespaceURI}.
38
+ */
39
+ // prettier-ignore
40
+ type DeferredPrefix =
41
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
42
+ | string
43
+ | null
44
+ | SourcePrefixUnspecified;
45
+
46
+ interface DeferredPrefixedQualifiedNameSource {
47
+ readonly namespaceURI: NamespaceURI | string;
48
+ readonly prefix: DeferredPrefix;
49
+ readonly localName: string;
50
+ }
51
+
52
+ // prettier-ignore
53
+ export type QualifiedNameSource =
54
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
55
+ | NamespaceQualifiedNameSource
56
+ | DeferredPrefixedQualifiedNameSource;
57
+
58
+ interface PrefixResolutionOptions {
59
+ lookupPrefix(namespaceURI: NamespaceURI | string): string | null;
60
+ }
61
+
62
+ /**
63
+ * @todo This is in the `lib` directory because it's a cross-cutting concern,
64
+ * applicable to:
65
+ *
66
+ * - Parsing XML into a useful runtime data model (usage which motivated initial
67
+ * development of this class)
68
+ * - Serializing XML from a runtime data model (also motivated initial dev)
69
+ * - `@getodk/xpath` (internal) e.g. references to
70
+ * {@link https://www.w3.org/TR/REC-xml-names/#NT-QName | QName} in various
71
+ * parts of XPath expression _syntax_, as well as various parts of the package
72
+ * interpreting those parts of syntax
73
+ * - `@getodk/xpath` (cross-package), e.g. in aspects of the
74
+ * {@link XPathDOMAdapter} APIs, and implementations thereof
75
+ * - A zillion potential optimizations, e.g. where names are useful in a lookup
76
+ * table (or used in conjunction with other information to construct keys for
77
+ * same)
78
+ *
79
+ * @todo As a cross-cutting concern, there are subtle but important differences
80
+ * between certain XPath and XML semantics around expressions of a "null"
81
+ * {@link prefix}. E.g. in the expression `/foo`, **technically** the `foo` Step
82
+ * should select child elements _in the null namespace_, whereas in most other
83
+ * cases a null prefix (when explicitly assigned `null`, rather than
84
+ * {@link DeferredPrefix | deferred for later resolution}) is expected to
85
+ * correspond _to the default namespace_ (whatever that is in the context of the
86
+ * {@link QualifiedName | qualified-named thing}).
87
+ *
88
+ * @todo As a mechanism for many optimizations, an evolution of this class would
89
+ * be **BY FAR** most useful if it can be treated as a _value type_, despite
90
+ * challenges using non-primitives as such in a JS runtime. To be clear: it
91
+ * would be most useful if every instance of {@link QualifiedName} having the
92
+ * same property values (or in some cases, the same combined
93
+ * {@link namespaceURI}/{@link localName} or combined
94
+ * {@link prefix}/{@link localName}) would also have _reference equality_ with
95
+ * other instances having the same property values (or pertinent subset
96
+ * thereof). Making a somewhat obvious point explicit: this would be
97
+ * particularly useful in cases where a lookup table is implemented as a native
98
+ * {@link Map}, where using {@link QualifiedName} as a key would break
99
+ * expectations (and probably quite a lot of functionality!) if 2+ equivalent
100
+ * keys mapped to different values.
101
+ *
102
+ * @todo Where we would want to treat instances as a value type, it would be
103
+ * useful to look at prior art for representation of the same data as a string.
104
+ * One frame of reference worth looking at is
105
+ * {@link https://www.w3.org/TR/xpath-30/#prod-xpath30-URIQualifiedName | XPath 3.0's URIQualifiedName}
106
+ * (but note that this syntax is mutually exclusive with the prefixed `QName`).
107
+ */
108
+ export class QualifiedName implements DeferredPrefixedQualifiedNameSource {
109
+ private readonly defaultPrefixResolutionOptions: PrefixResolutionOptions;
110
+
111
+ readonly namespaceURI: NamespaceURI;
112
+
113
+ /**
114
+ * @see {@link SourcePrefixUnspecified}, {@link DeferredPrefix}
115
+ */
116
+ readonly prefix: DeferredPrefix;
117
+
118
+ readonly localName: string;
119
+
120
+ constructor(source: QualifiedNameSource) {
121
+ const { localName } = source;
122
+
123
+ let prefix = source.prefix;
124
+
125
+ if (typeof prefix === 'undefined') {
126
+ prefix = SOURCE_PREFIX_UNSPECIFIED;
127
+ }
128
+
129
+ const namespaceURI = NamespaceURL.from(source.namespaceURI);
130
+
131
+ this.namespaceURI = namespaceURI;
132
+ this.prefix = prefix;
133
+ this.localName = localName;
134
+
135
+ this.defaultPrefixResolutionOptions = {
136
+ lookupPrefix: () => {
137
+ if (prefix === SOURCE_PREFIX_UNSPECIFIED) {
138
+ throw new Error(`Failed to resolve prefix for namespace URI: ${String(namespaceURI)}`);
139
+ }
140
+
141
+ return prefix;
142
+ },
143
+ };
144
+ }
145
+
146
+ /**
147
+ * @todo at time of writing, it's not expected we will actually supply
148
+ * {@link options} in calls to this method! Current calls are from definitions
149
+ * whose prefixes are known at parse time (i.e. they are prefixed in the
150
+ * source XML from which they're parsed).
151
+ *
152
+ * The intent of accepting the options here now is to leave a fairly large
153
+ * breadcrumb, for any use case where we might want to serialize XML from
154
+ * artificially constructed DOM-like trees (e.g. `StaticNode` implementations
155
+ * defined by parsing non-XML external secondary instances such as CSV and
156
+ * GeoJSON). AFAIK this doesn't correspond to any known feature in the "like
157
+ * Collect" scope, but it could have implications for inspecting form details
158
+ * in e.g. "debug/form design/dev mode" scenarios.
159
+ */
160
+ getPrefixedName(options: PrefixResolutionOptions = this.defaultPrefixResolutionOptions): string {
161
+ const { namespaceURI, localName } = this;
162
+ const prefix = options.lookupPrefix(namespaceURI);
163
+
164
+ if (prefix == null) {
165
+ return localName;
166
+ }
167
+
168
+ return `${prefix}:${localName}`;
169
+ }
170
+ }
@@ -0,0 +1,12 @@
1
+ import { XFORMS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
2
+ import { QualifiedName } from './QualifiedName.ts';
3
+
4
+ export class UnprefixedXFormsName extends QualifiedName {
5
+ constructor(localName: string) {
6
+ super({
7
+ namespaceURI: XFORMS_NAMESPACE_URI,
8
+ prefix: null,
9
+ localName,
10
+ });
11
+ }
12
+ }
@@ -0,0 +1,25 @@
1
+ export const parseToInteger = (value: string | null): number | null => {
2
+ if (value === null) {
3
+ return null;
4
+ }
5
+
6
+ const parsed = Number(value);
7
+ if (typeof value !== 'string' || value.trim() === '' || !Number.isInteger(parsed)) {
8
+ throw new Error(`Expected an integer, but got: ${value}`);
9
+ }
10
+
11
+ return parsed;
12
+ };
13
+
14
+ export const parseToFloat = (value: string | null): number | null => {
15
+ if (value === null) {
16
+ return null;
17
+ }
18
+
19
+ const parsed = Number(value);
20
+ if (typeof value !== 'string' || value.trim() === '' || Number.isNaN(parsed)) {
21
+ throw new Error(`Expected a float, but got: ${value}`);
22
+ }
23
+
24
+ return parsed;
25
+ };
@@ -1,50 +1,27 @@
1
1
  import type { Signal } from 'solid-js';
2
2
  import { createComputed, createMemo, createSignal, untrack } from 'solid-js';
3
- import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
4
3
  import type { InstanceValueContext } from '../../instance/internal-api/InstanceValueContext.ts';
5
4
  import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
6
5
  import { createComputedExpression } from './createComputedExpression.ts';
7
6
  import type { SimpleAtomicState, SimpleAtomicStateSetter } from './types.ts';
8
7
 
9
- type InitialValueSource = 'FORM_DEFAULT' | 'PRIMARY_INSTANCE';
10
-
11
- export interface InstanceValueStateOptions {
12
- /**
13
- * Specifies the source of a {@link createInstanceValueState} signal's initial
14
- * value state, where:
15
- *
16
- * - 'FORM_DEFAULT': Derives the initial state from the form's definition of
17
- * the node itself. This is the default option, appropriate when
18
- * initializing a form without additional primary instance data. In other
19
- * words, this value should not be used for edits.
20
- *
21
- * - 'PRIMARY_INSTANCE': Derives the initial state from the current text
22
- * content of the {@link ValueNode.contextNode}. This option should be
23
- * specified when initializing a form with existing primary instance data,
24
- * such as when editing a previous submission.
25
- *
26
- * @default 'FORM_DEFAULT'
27
- *
28
- * Specifies whether a {@link createInstanceValueState} signal's initial state
29
- * should be derived from the current text content of the
30
- * {@link ValueNode.contextNode | primary instance DOM state}.
31
- */
32
- readonly initialValueSource?: InitialValueSource;
33
- }
34
-
35
- const getInitialValue = (
36
- context: InstanceValueContext,
37
- options: InstanceValueStateOptions
38
- ): string => {
39
- const { initialValueSource = 'FORM_DEFAULT' } = options;
8
+ const isInstanceFirstLoad = (context: InstanceValueContext) => {
9
+ return context.rootDocument.initializationMode === 'create';
10
+ };
40
11
 
41
- if (initialValueSource === 'FORM_DEFAULT') {
42
- const { defaultValue } = context.definition;
12
+ /**
13
+ * Special case, does not correspond to any event.
14
+ *
15
+ * @see {@link shouldPreloadUID}
16
+ */
17
+ const isEditInitialLoad = (context: InstanceValueContext) => {
18
+ return context.rootDocument.initializationMode === 'edit';
19
+ };
43
20
 
44
- return context.decodeInstanceValue(defaultValue);
45
- }
21
+ const getInitialValue = (context: InstanceValueContext): string => {
22
+ const sourceNode = context.instanceNode ?? context.definition.template;
46
23
 
47
- throw new ErrorProductionDesignPendingError('Edit implementation pending');
24
+ return context.decodeInstanceValue(sourceNode.value);
48
25
  };
49
26
 
50
27
  type BaseValueState = Signal<string>;
@@ -106,10 +83,56 @@ const guardDownstreamReadonlyWrites = (
106
83
  return [getValue, setValue];
107
84
  };
108
85
 
86
+ /**
87
+ * Per {@link https://getodk.github.io/xforms-spec/#preload-attributes:~:text=concatenation%20of%20%E2%80%98uuid%3A%E2%80%99%20and%20uuid()}
88
+ */
89
+ const PRELOAD_UID_EXPRESSION = 'concat("uuid:", uuid())';
90
+
91
+ /**
92
+ * @todo It feels increasingly awkward to keep piling up preload stuff here, but it won't stay that way for long. In the meantime, this seems like the best way to express the cases where `preload="uid"` should be effective, i.e.:
93
+ *
94
+ * - When an instance is first loaded ({@link isInstanceFirstLoad})
95
+ * - When an instance is initially loaded for editing ({@link isEditInitialLoad})
96
+ */
97
+ const shouldPreloadUID = (context: InstanceValueContext) => {
98
+ return isInstanceFirstLoad(context) || isEditInitialLoad(context);
99
+ };
100
+
101
+ /**
102
+ * @todo This is a temporary one-off, until we support the full range of
103
+ * {@link https://getodk.github.io/xforms-spec/#preload-attributes | preloads}.
104
+ *
105
+ * @todo ALSO, IMPORTANTLY(!): the **call site** for this function is
106
+ * semantically where we would expect to trigger a
107
+ * {@link https://getodk.github.io/xforms-spec/#event:odk-instance-first-load | odk-instance-first-load event},
108
+ * _and compute_ preloads semantically associated with that event.
109
+ */
110
+ const setPreloadUIDValue = (
111
+ context: InstanceValueContext,
112
+ valueState: RelevantValueState
113
+ ): void => {
114
+ const { preload } = context.definition.bind;
115
+
116
+ if (preload?.type !== 'uid' || !shouldPreloadUID(context)) {
117
+ return;
118
+ }
119
+
120
+ const preloadUIDValue = context.evaluator.evaluateString(PRELOAD_UID_EXPRESSION, {
121
+ contextNode: context.contextNode,
122
+ });
123
+
124
+ const [, setValue] = valueState;
125
+
126
+ setValue(preloadUIDValue);
127
+ };
128
+
109
129
  /**
110
130
  * Defines a reactive effect which writes the result of `calculate` bind
111
131
  * computations to the provided value setter, on initialization and any
112
132
  * subsequent reactive update.
133
+ *
134
+ * @see {@link setPreloadUIDValue} for important details about spec ordering of
135
+ * events and computations.
113
136
  */
114
137
  const createCalculation = (
115
138
  context: InstanceValueContext,
@@ -138,21 +161,24 @@ export type InstanceValueState = SimpleAtomicState<string>;
138
161
  * Provides a consistent interface for value nodes of any type which:
139
162
  *
140
163
  * - derives initial state from either an existing instance (e.g. for edits) or
141
- * the node's definition (e.g. initializing a new submission)
164
+ * the node's definition (e.g. initializing a new instance)
142
165
  * - decodes current primary instance state into the value node's runtime type
143
166
  * - encodes updated runtime values to store updated instance state
144
167
  * - initializes reactive computation of `calculate` bind expressions for those
145
168
  * nodes defined with one
146
169
  * - prevents downstream writes to nodes in a readonly state
147
170
  */
148
- export const createInstanceValueState = (
149
- context: InstanceValueContext,
150
- options: InstanceValueStateOptions = {}
151
- ): InstanceValueState => {
171
+ export const createInstanceValueState = (context: InstanceValueContext): InstanceValueState => {
152
172
  return context.scope.runTask(() => {
153
- const initialValue = getInitialValue(context, options);
173
+ const initialValue = getInitialValue(context);
154
174
  const baseValueState = createSignal(initialValue);
155
175
  const relevantValueState = createRelevantValueState(context, baseValueState);
176
+
177
+ /**
178
+ * @see {@link setPreloadUIDValue} for important details about spec ordering of events and computations.
179
+ */
180
+ setPreloadUIDValue(context, relevantValueState);
181
+
156
182
  const { calculate } = context.definition.bind;
157
183
 
158
184
  if (calculate != null) {
@@ -1,21 +1,26 @@
1
1
  import { UpsertableMap } from '@getodk/common/lib/collections/UpsertableMap.ts';
2
2
  import type { Accessor } from 'solid-js';
3
3
  import { createMemo } from 'solid-js';
4
+ import type { ActiveLanguage } from '../../client/FormLanguage.ts';
5
+ import type { SelectItem } from '../../client/SelectNode.ts';
6
+ import type { RankItem } from '../../client/RankNode.ts';
4
7
  import type { TextRange as ClientTextRange } from '../../client/TextRange.ts';
5
- import type { ActiveLanguage, SelectItem } from '../../index.ts';
6
8
  import type { EvaluationContext } from '../../instance/internal-api/EvaluationContext.ts';
7
9
  import type { TranslationContext } from '../../instance/internal-api/TranslationContext.ts';
8
- import type { SelectField } from '../../instance/SelectField.ts';
10
+ import type { SelectControl } from '../../instance/SelectControl.ts';
11
+ import type { RankControl } from '../../instance/RankControl.ts';
9
12
  import { TextChunk } from '../../instance/text/TextChunk.ts';
10
13
  import { TextRange } from '../../instance/text/TextRange.ts';
11
14
  import type { EngineXPathNode } from '../../integration/xpath/adapter/kind.ts';
12
15
  import type { EngineXPathEvaluator } from '../../integration/xpath/EngineXPathEvaluator.ts';
13
- import type { ItemDefinition } from '../../parse/body/control/select/ItemDefinition.ts';
14
- import type { ItemsetDefinition } from '../../parse/body/control/select/ItemsetDefinition.ts';
16
+ import type { ItemDefinition } from '../../parse/body/control/ItemDefinition.ts';
17
+ import type { ItemsetDefinition } from '../../parse/body/control/ItemsetDefinition.ts';
15
18
  import { createComputedExpression } from './createComputedExpression.ts';
16
19
  import type { ReactiveScope } from './scope.ts';
17
20
  import { createTextRange } from './text/createTextRange.ts';
18
21
 
22
+ export type ItemCollectionControl = RankControl | SelectControl;
23
+ type Item = RankItem | SelectItem;
19
24
  type DerivedItemLabel = ClientTextRange<'item-label', 'form-derived'>;
20
25
 
21
26
  const derivedItemLabel = (context: TranslationContext, value: string): DerivedItemLabel => {
@@ -24,7 +29,7 @@ const derivedItemLabel = (context: TranslationContext, value: string): DerivedIt
24
29
  return new TextRange('form-derived', 'item-label', [chunk]);
25
30
  };
26
31
 
27
- const createSelectItemLabel = (
32
+ const createItemLabel = (
28
33
  context: EvaluationContext,
29
34
  definition: ItemDefinition
30
35
  ): Accessor<ClientTextRange<'item-label'>> => {
@@ -37,14 +42,14 @@ const createSelectItemLabel = (
37
42
  return createTextRange(context, 'item-label', label);
38
43
  };
39
44
 
40
- const createTranslatedStaticSelectItems = (
41
- selectField: SelectField,
45
+ const createTranslatedStaticItems = (
46
+ control: ItemCollectionControl,
42
47
  items: readonly ItemDefinition[]
43
- ): Accessor<readonly SelectItem[]> => {
44
- return selectField.scope.runTask(() => {
48
+ ): Accessor<readonly Item[]> => {
49
+ return control.scope.runTask(() => {
45
50
  const labeledItems = items.map((item) => {
46
51
  const { value } = item;
47
- const label = createSelectItemLabel(selectField, item);
52
+ const label = createItemLabel(control, item);
48
53
 
49
54
  return () => ({
50
55
  value,
@@ -66,18 +71,18 @@ class ItemsetItemEvaluationContext implements EvaluationContext {
66
71
  readonly getActiveLanguage: Accessor<ActiveLanguage>;
67
72
 
68
73
  constructor(
69
- selectField: SelectField,
74
+ control: ItemCollectionControl,
70
75
  readonly contextNode: EngineXPathNode
71
76
  ) {
72
- this.isAttached = selectField.isAttached;
73
- this.scope = selectField.scope;
74
- this.evaluator = selectField.evaluator;
75
- this.contextReference = selectField.contextReference;
76
- this.getActiveLanguage = selectField.getActiveLanguage;
77
+ this.isAttached = control.isAttached;
78
+ this.scope = control.scope;
79
+ this.evaluator = control.evaluator;
80
+ this.contextReference = control.contextReference;
81
+ this.getActiveLanguage = control.getActiveLanguage;
77
82
  }
78
83
  }
79
84
 
80
- const createSelectItemsetItemLabel = (
85
+ const createItemsetItemLabel = (
81
86
  context: EvaluationContext,
82
87
  definition: ItemsetDefinition,
83
88
  itemValue: Accessor<string>
@@ -99,11 +104,11 @@ interface ItemsetItem {
99
104
  }
100
105
 
101
106
  const createItemsetItems = (
102
- selectField: SelectField,
107
+ control: ItemCollectionControl,
103
108
  itemset: ItemsetDefinition
104
109
  ): Accessor<readonly ItemsetItem[]> => {
105
- return selectField.scope.runTask(() => {
106
- const itemNodes = createComputedExpression(selectField, itemset.nodes, {
110
+ return control.scope.runTask(() => {
111
+ const itemNodes = createComputedExpression(control, itemset.nodes, {
107
112
  defaultValue: [],
108
113
  });
109
114
  const itemsCache = new UpsertableMap<EngineXPathNode, ItemsetItem>();
@@ -111,11 +116,11 @@ const createItemsetItems = (
111
116
  return createMemo(() => {
112
117
  return itemNodes().map((itemNode) => {
113
118
  return itemsCache.upsert(itemNode, () => {
114
- const context = new ItemsetItemEvaluationContext(selectField, itemNode);
119
+ const context = new ItemsetItemEvaluationContext(control, itemNode);
115
120
  const value = createComputedExpression(context, itemset.value, {
116
121
  defaultValue: '',
117
122
  });
118
- const label = createSelectItemsetItemLabel(context, itemset, value);
123
+ const label = createItemsetItemLabel(context, itemset, value);
119
124
 
120
125
  return {
121
126
  label,
@@ -128,11 +133,11 @@ const createItemsetItems = (
128
133
  };
129
134
 
130
135
  const createItemset = (
131
- selectField: SelectField,
136
+ control: ItemCollectionControl,
132
137
  itemset: ItemsetDefinition
133
- ): Accessor<readonly SelectItem[]> => {
134
- return selectField.scope.runTask(() => {
135
- const itemsetItems = createItemsetItems(selectField, itemset);
138
+ ): Accessor<readonly Item[]> => {
139
+ return control.scope.runTask(() => {
140
+ const itemsetItems = createItemsetItems(control, itemset);
136
141
 
137
142
  return createMemo(() => {
138
143
  return itemsetItems().map((item) => {
@@ -146,23 +151,23 @@ const createItemset = (
146
151
  };
147
152
 
148
153
  /**
149
- * Creates a reactive computation of a {@link SelectField}'s
150
- * {@link SelectItem}s, in support of the field's `valueOptions`.
154
+ * Creates a reactive computation of a {@link ItemCollectionControl}'s
155
+ * {@link Item}s, in support of the field's `valueOptions`.
151
156
  *
152
- * - Selects defined with static `<item>`s will compute to an corresponding
157
+ * - The control defined with static `<item>`s will compute to an corresponding
153
158
  * static list of items.
154
- * - Selects defined with a computed `<itemset>` will compute to a reactive list
159
+ * - The control defined with a computed `<itemset>` will compute to a reactive list
155
160
  * of items.
156
- * - Items of both will produce {@link SelectItem.label | labels} reactive to
161
+ * - Items of both will produce {@link ItemType.label | labels} reactive to
157
162
  * their appropriate dependencies (whether relative to the itemset item node,
158
163
  * referencing a form's `itext` translations, etc).
159
164
  */
160
- export const createSelectItems = (selectField: SelectField): Accessor<readonly SelectItem[]> => {
161
- const { items, itemset } = selectField.definition.bodyElement;
165
+ export const createItemCollection = (control: ItemCollectionControl): Accessor<readonly Item[]> => {
166
+ const { items, itemset } = control.definition.bodyElement;
162
167
 
163
- if (itemset == null) {
164
- return createTranslatedStaticSelectItems(selectField, items);
168
+ if (itemset != null) {
169
+ return createItemset(control, itemset);
165
170
  }
166
171
 
167
- return createItemset(selectField, itemset);
172
+ return createTranslatedStaticItems(control, items);
168
173
  };
@@ -1,3 +1,6 @@
1
+ import type { NamespaceDeclarationMap } from './names/NamespaceDeclarationMap.ts';
2
+ import type { QualifiedName } from './names/QualifiedName.ts';
3
+
1
4
  declare const ESCAPED_XML_TEXT_BRAND: unique symbol;
2
5
 
3
6
  export type EscapedXMLText = string & { readonly [ESCAPED_XML_TEXT_BRAND]: true };
@@ -75,22 +78,86 @@ export const escapeXMLText = <Text extends string>(
75
78
  : (out as EscapedXMLText);
76
79
  };
77
80
 
78
- const serializeElementXML = (nodeName: string, children: string): string => {
81
+ interface SerializableElementAttribute {
82
+ serializeAttributeXML(): string;
83
+ }
84
+
85
+ interface ElementXMLSerializationOptions {
86
+ readonly namespaceDeclarations?: NamespaceDeclarationMap;
87
+ readonly attributes?: readonly SerializableElementAttribute[];
88
+ }
89
+
90
+ const serializeElementNamespaceDeclarationXML = (
91
+ namespaceDeclarations?: NamespaceDeclarationMap
92
+ ): string => {
93
+ if (namespaceDeclarations == null) {
94
+ return '';
95
+ }
96
+
97
+ return Array.from(namespaceDeclarations.values())
98
+ .map((namespaceDeclaration) => {
99
+ return namespaceDeclaration.serializeNamespaceDeclarationXML({
100
+ omitDefaultNamespace: true,
101
+ });
102
+ })
103
+ .join('');
104
+ };
105
+
106
+ const serializeElementAttributeXML = (
107
+ attributes?: readonly SerializableElementAttribute[]
108
+ ): string => {
109
+ if (attributes == null) {
110
+ return '';
111
+ }
112
+
113
+ return attributes
114
+ .map((attribute) => {
115
+ return attribute.serializeAttributeXML();
116
+ })
117
+ .join('');
118
+ };
119
+
120
+ const serializeElementXML = (
121
+ qualifiedName: QualifiedName,
122
+ children: string,
123
+ options: ElementXMLSerializationOptions = {}
124
+ ): string => {
125
+ // See JSDoc for the `getPrefixedName` method. If we find we do actually need
126
+ // custom element (subtree) prefix resolution, we'd uncomment the argument
127
+ // below. (Either way, at time of writing the affected tests pass where
128
+ // expected when the option is passed. It's omitted on the presumption that it
129
+ // would be redundant, since the nodes being serialized are already resolved
130
+ // with the same set of namespace declarations which would affect them.)
131
+ //
132
+ // prettier-ignore
133
+ const nodeName = qualifiedName.getPrefixedName(
134
+ // options.namespaceDeclarations
135
+ );
136
+ const namespaceDeclarations = serializeElementNamespaceDeclarationXML(
137
+ options.namespaceDeclarations
138
+ );
139
+ const attributes = serializeElementAttributeXML(options.attributes);
140
+ const prefix = `<${nodeName}${namespaceDeclarations}${attributes}`;
141
+
79
142
  if (children === '') {
80
- return `<${nodeName}/>`;
143
+ return `${prefix}/>`;
81
144
  }
82
145
 
83
- // TODO: attributes
84
- return `<${nodeName}>${children}</${nodeName}>`;
146
+ return `${prefix}>${children}</${nodeName}>`;
85
147
  };
86
148
 
87
149
  export const serializeParentElementXML = (
88
- nodeName: string,
89
- serializedChildren: readonly string[]
150
+ qualifiedName: QualifiedName,
151
+ serializedChildren: readonly string[],
152
+ options?: ElementXMLSerializationOptions
90
153
  ): string => {
91
- return serializeElementXML(nodeName, serializedChildren.join(''));
154
+ return serializeElementXML(qualifiedName, serializedChildren.join(''), options);
92
155
  };
93
156
 
94
- export const serializeLeafElementXML = (nodeName: string, xmlValue: EscapedXMLText): string => {
95
- return serializeElementXML(nodeName, xmlValue.normalize());
157
+ export const serializeLeafElementXML = (
158
+ qualifiedName: QualifiedName,
159
+ xmlValue: EscapedXMLText,
160
+ options?: ElementXMLSerializationOptions
161
+ ): string => {
162
+ return serializeElementXML(qualifiedName, xmlValue.normalize(), options);
96
163
  };