@getodk/xforms-engine 0.6.0 → 0.8.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 (332) hide show
  1. package/dist/client/BaseNode.d.ts +4 -4
  2. package/dist/client/BaseValueNode.d.ts +7 -3
  3. package/dist/client/RootNode.d.ts +20 -16
  4. package/dist/client/UploadNode.d.ts +53 -0
  5. package/dist/client/attachments/InstanceAttachmentMeta.d.ts +8 -0
  6. package/dist/client/attachments/InstanceAttachmentsConfig.d.ts +8 -0
  7. package/dist/client/constants.d.ts +11 -12
  8. package/dist/client/form/CreateFormInstance.d.ts +14 -0
  9. package/dist/client/form/EditFormInstance.d.ts +62 -0
  10. package/dist/client/form/FormInstance.d.ts +104 -0
  11. package/dist/client/form/FormInstanceConfig.d.ts +19 -0
  12. package/dist/client/form/FormResource.d.ts +1 -0
  13. package/dist/client/form/LoadForm.d.ts +79 -0
  14. package/dist/client/form/LoadFormResult.d.ts +67 -0
  15. package/dist/client/form/RestoreFormInstance.d.ts +8 -0
  16. package/dist/client/hierarchy.d.ts +4 -5
  17. package/dist/client/index.d.ts +40 -11
  18. package/dist/client/node-types.d.ts +2 -3
  19. package/dist/client/repeat/BaseRepeatRangeNode.d.ts +3 -4
  20. package/dist/client/repeat/RepeatInstanceNode.d.ts +4 -5
  21. package/dist/client/repeat/RepeatRangeControlledNode.d.ts +2 -2
  22. package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +2 -2
  23. package/dist/client/resources.d.ts +1 -1
  24. package/dist/client/serialization/InstanceData.d.ts +14 -0
  25. package/dist/client/serialization/InstanceFile.d.ts +6 -0
  26. package/dist/client/serialization/InstancePayload.d.ts +93 -0
  27. package/dist/client/serialization/InstancePayloadOptions.d.ts +24 -0
  28. package/dist/client/serialization/InstanceState.d.ts +12 -0
  29. package/dist/client/submission/{SubmissionDefinition.d.ts → SubmissionMeta.d.ts} +1 -1
  30. package/dist/entrypoints/FormInstance.d.ts +20 -0
  31. package/dist/entrypoints/FormResult/BaseFormResult.d.ts +22 -0
  32. package/dist/entrypoints/FormResult/BaseInstantiableFormResult.d.ts +25 -0
  33. package/dist/entrypoints/FormResult/FormFailureResult.d.ts +17 -0
  34. package/dist/entrypoints/FormResult/FormSuccessResult.d.ts +15 -0
  35. package/dist/entrypoints/FormResult/FormWarningResult.d.ts +15 -0
  36. package/dist/entrypoints/createInstance.d.ts +9 -0
  37. package/dist/entrypoints/editInstance.d.ts +9 -0
  38. package/dist/entrypoints/index.d.ts +4 -0
  39. package/dist/entrypoints/loadForm.d.ts +4 -0
  40. package/dist/entrypoints/restoreInstance.d.ts +9 -0
  41. package/dist/error/LoadFormFailureError.d.ts +9 -0
  42. package/dist/error/MalformedInstanceDataError.d.ts +3 -0
  43. package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +22 -0
  44. package/dist/error/UploadValueTypeError.d.ts +8 -0
  45. package/dist/index.d.ts +2 -33
  46. package/dist/index.js +8280 -6779
  47. package/dist/index.js.map +1 -1
  48. package/dist/instance/Group.d.ts +6 -5
  49. package/dist/instance/InputControl.d.ts +5 -4
  50. package/dist/instance/ModelValue.d.ts +5 -4
  51. package/dist/instance/Note.d.ts +4 -3
  52. package/dist/instance/PrimaryInstance.d.ts +34 -8
  53. package/dist/instance/RangeControl.d.ts +5 -4
  54. package/dist/instance/RankControl.d.ts +6 -5
  55. package/dist/instance/Root.d.ts +7 -9
  56. package/dist/instance/SelectControl.d.ts +4 -3
  57. package/dist/instance/Subtree.d.ts +6 -5
  58. package/dist/instance/TriggerControl.d.ts +4 -3
  59. package/dist/instance/UploadControl.d.ts +58 -0
  60. package/dist/instance/abstract/DescendantNode.d.ts +10 -1
  61. package/dist/instance/abstract/InstanceNode.d.ts +7 -4
  62. package/dist/instance/abstract/ValueNode.d.ts +7 -5
  63. package/dist/instance/attachments/InstanceAttachment.d.ts +42 -0
  64. package/dist/instance/attachments/InstanceAttachmentsState.d.ts +9 -0
  65. package/dist/instance/children/DescendantNodeInitOptions.d.ts +32 -0
  66. package/dist/instance/{children.d.ts → children/buildChildren.d.ts} +1 -1
  67. package/dist/instance/children/childrenInitOptions.d.ts +9 -0
  68. package/dist/instance/children/normalizeChildInitOptions.d.ts +2 -0
  69. package/dist/instance/hierarchy.d.ts +6 -7
  70. package/dist/instance/input/InitialInstanceState.d.ts +13 -0
  71. package/dist/instance/input/InstanceAttachmentMap.d.ts +19 -0
  72. package/dist/instance/internal-api/InstanceAttachmentContext.d.ts +19 -0
  73. package/dist/instance/internal-api/InstanceConfig.d.ts +4 -9
  74. package/dist/instance/internal-api/InstanceValueContext.d.ts +8 -1
  75. package/dist/instance/internal-api/serialization/ClientReactiveSerializableInstance.d.ts +16 -0
  76. package/dist/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.d.ts +32 -0
  77. package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +18 -0
  78. package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +13 -0
  79. package/dist/instance/internal-api/serialization/ClientReactiveSerializableValueNode.d.ts +21 -0
  80. package/dist/instance/repeat/BaseRepeatRange.d.ts +10 -8
  81. package/dist/instance/repeat/RepeatInstance.d.ts +10 -7
  82. package/dist/instance/repeat/RepeatRangeControlled.d.ts +27 -3
  83. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +4 -3
  84. package/dist/instance/resource.d.ts +5 -1
  85. package/dist/integration/xpath/EngineXPathEvaluator.d.ts +2 -2
  86. package/dist/integration/xpath/adapter/kind.d.ts +4 -10
  87. package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +4 -5
  88. package/dist/integration/xpath/static-dom/StaticDocument.d.ts +13 -10
  89. package/dist/integration/xpath/static-dom/StaticElement.d.ts +21 -22
  90. package/dist/integration/xpath/static-dom/StaticNode.d.ts +1 -1
  91. package/dist/integration/xpath/static-dom/StaticParentNode.d.ts +13 -0
  92. package/dist/integration/xpath/static-dom/staticNodeName.d.ts +3 -0
  93. package/dist/lib/client-reactivity/instance-state/createNodeRangeInstanceState.d.ts +4 -0
  94. package/dist/lib/client-reactivity/instance-state/createParentNodeInstanceState.d.ts +4 -0
  95. package/dist/lib/client-reactivity/instance-state/createPrimaryInstanceState.d.ts +3 -0
  96. package/dist/lib/client-reactivity/instance-state/createRootInstanceState.d.ts +3 -0
  97. package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +6 -0
  98. package/dist/lib/client-reactivity/instance-state/createValueNodeInstanceState.d.ts +3 -0
  99. package/dist/lib/client-reactivity/instance-state/prepareInstancePayload.d.ts +8 -0
  100. package/dist/lib/names/UnprefixedXFormsName.d.ts +4 -0
  101. package/dist/lib/reactivity/createInstanceAttachment.d.ts +8 -0
  102. package/dist/lib/reactivity/createInstanceValueState.d.ts +2 -27
  103. package/dist/lib/resource-helpers.d.ts +2 -0
  104. package/dist/parse/XFormDOM.d.ts +1 -1
  105. package/dist/parse/body/BodyDefinition.d.ts +2 -1
  106. package/dist/parse/body/control/UploadControlDefinition.d.ts +2 -0
  107. package/dist/parse/model/BindDefinition.d.ts +1 -1
  108. package/dist/parse/model/BindTypeDefinition.d.ts +2 -7
  109. package/dist/parse/model/ItextTranslationsDefinition.d.ts +18 -0
  110. package/dist/parse/model/LeafNodeDefinition.d.ts +4 -5
  111. package/dist/parse/model/ModelBindMap.d.ts +1 -1
  112. package/dist/parse/model/ModelDefinition.d.ts +9 -2
  113. package/dist/parse/model/NodeDefinition.d.ts +18 -30
  114. package/dist/parse/model/NoteNodeDefinition.d.ts +3 -2
  115. package/dist/parse/model/RangeNodeDefinition.d.ts +2 -1
  116. package/dist/parse/model/RepeatDefinition.d.ts +62 -0
  117. package/dist/parse/model/RootAttributeDefinition.d.ts +1 -4
  118. package/dist/parse/model/RootAttributeMap.d.ts +2 -1
  119. package/dist/parse/model/RootDefinition.d.ts +7 -8
  120. package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +15 -2
  121. package/dist/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.d.ts +5 -0
  122. package/dist/parse/model/SecondaryInstance/defineSecondaryInstance.d.ts +5 -0
  123. package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +1 -7
  124. package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +1 -1
  125. package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +1 -1
  126. package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +1 -1
  127. package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +1 -1
  128. package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +1 -1
  129. package/dist/parse/model/{FormSubmissionDefinition.d.ts → SubmissionDefinition.d.ts} +2 -2
  130. package/dist/parse/model/SubtreeDefinition.d.ts +4 -5
  131. package/dist/parse/model/nodeDefinitionMap.d.ts +5 -0
  132. package/dist/parse/shared/parseInstanceXML.d.ts +21 -0
  133. package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +4 -21
  134. package/dist/solid.js +8251 -6751
  135. package/dist/solid.js.map +1 -1
  136. package/package.json +15 -14
  137. package/src/client/BaseNode.ts +4 -4
  138. package/src/client/BaseValueNode.ts +7 -3
  139. package/src/client/RootNode.ts +32 -19
  140. package/src/client/UploadNode.ts +78 -0
  141. package/src/client/attachments/InstanceAttachmentMeta.ts +10 -0
  142. package/src/client/attachments/InstanceAttachmentsConfig.ts +13 -0
  143. package/src/client/constants.ts +12 -14
  144. package/src/client/form/CreateFormInstance.ts +19 -0
  145. package/src/client/form/EditFormInstance.ts +93 -0
  146. package/src/client/form/FormInstance.ts +114 -0
  147. package/src/client/form/FormInstanceConfig.ts +21 -0
  148. package/src/client/form/FormResource.ts +1 -0
  149. package/src/client/form/LoadForm.ts +92 -0
  150. package/src/client/form/LoadFormResult.ts +103 -0
  151. package/src/client/form/RestoreFormInstance.ts +14 -0
  152. package/src/client/hierarchy.ts +5 -8
  153. package/src/client/index.ts +49 -29
  154. package/src/client/node-types.ts +3 -8
  155. package/src/client/repeat/BaseRepeatRangeNode.ts +3 -4
  156. package/src/client/repeat/RepeatInstanceNode.ts +4 -8
  157. package/src/client/repeat/RepeatRangeControlledNode.ts +2 -2
  158. package/src/client/repeat/RepeatRangeUncontrolledNode.ts +2 -2
  159. package/src/client/resources.ts +2 -2
  160. package/src/client/serialization/InstanceData.ts +24 -0
  161. package/src/client/serialization/InstanceFile.ts +9 -0
  162. package/src/client/serialization/InstancePayload.ts +126 -0
  163. package/src/client/serialization/InstancePayloadOptions.ts +29 -0
  164. package/src/client/serialization/InstanceState.ts +14 -0
  165. package/src/client/submission/{SubmissionDefinition.ts → SubmissionMeta.ts} +1 -1
  166. package/src/entrypoints/FormInstance.ts +56 -0
  167. package/src/entrypoints/FormResult/BaseFormResult.ts +40 -0
  168. package/src/entrypoints/FormResult/BaseInstantiableFormResult.ts +109 -0
  169. package/src/entrypoints/FormResult/FormFailureResult.ts +44 -0
  170. package/src/entrypoints/FormResult/FormSuccessResult.ts +25 -0
  171. package/src/entrypoints/FormResult/FormWarningResult.ts +25 -0
  172. package/src/entrypoints/createInstance.ts +23 -0
  173. package/src/entrypoints/editInstance.ts +24 -0
  174. package/src/entrypoints/index.ts +4 -0
  175. package/src/entrypoints/loadForm.ts +154 -0
  176. package/src/entrypoints/restoreInstance.ts +27 -0
  177. package/src/error/LoadFormFailureError.ts +114 -0
  178. package/src/error/MalformedInstanceDataError.ts +3 -0
  179. package/src/error/TemplatedNodeAttributeSerializationError.ts +24 -0
  180. package/src/error/UploadValueTypeError.ts +13 -0
  181. package/src/index.ts +2 -46
  182. package/src/instance/Group.ts +16 -15
  183. package/src/instance/InputControl.ts +17 -11
  184. package/src/instance/ModelValue.ts +17 -11
  185. package/src/instance/Note.ts +10 -9
  186. package/src/instance/PrimaryInstance.ts +68 -31
  187. package/src/instance/RangeControl.ts +17 -11
  188. package/src/instance/RankControl.ts +28 -19
  189. package/src/instance/Root.ts +20 -31
  190. package/src/instance/SelectControl.ts +21 -12
  191. package/src/instance/Subtree.ts +16 -15
  192. package/src/instance/TriggerControl.ts +21 -12
  193. package/src/instance/UploadControl.ts +184 -0
  194. package/src/instance/abstract/DescendantNode.ts +12 -2
  195. package/src/instance/abstract/InstanceNode.ts +9 -5
  196. package/src/instance/abstract/ValueNode.ts +11 -13
  197. package/src/instance/attachments/InstanceAttachment.ts +69 -0
  198. package/src/instance/attachments/InstanceAttachmentsState.ts +18 -0
  199. package/src/instance/children/DescendantNodeInitOptions.ts +35 -0
  200. package/src/instance/{children.ts → children/buildChildren.ts} +57 -53
  201. package/src/instance/children/childrenInitOptions.ts +117 -0
  202. package/src/instance/children/normalizeChildInitOptions.ts +332 -0
  203. package/src/instance/hierarchy.ts +6 -9
  204. package/src/instance/input/InitialInstanceState.ts +108 -0
  205. package/src/instance/input/InstanceAttachmentMap.ts +154 -0
  206. package/src/instance/internal-api/InstanceAttachmentContext.ts +20 -0
  207. package/src/instance/internal-api/InstanceConfig.ts +6 -10
  208. package/src/instance/internal-api/InstanceValueContext.ts +9 -1
  209. package/src/instance/internal-api/serialization/ClientReactiveSerializableInstance.ts +22 -0
  210. package/src/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.ts +43 -0
  211. package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +26 -0
  212. package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +24 -0
  213. package/src/instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts +28 -0
  214. package/src/instance/repeat/BaseRepeatRange.ts +19 -24
  215. package/src/instance/repeat/RepeatInstance.ts +26 -19
  216. package/src/instance/repeat/RepeatRangeControlled.ts +90 -17
  217. package/src/instance/repeat/RepeatRangeUncontrolled.ts +10 -9
  218. package/src/instance/resource.ts +14 -1
  219. package/src/integration/xpath/EngineXPathEvaluator.ts +2 -2
  220. package/src/integration/xpath/adapter/kind.ts +1 -28
  221. package/src/integration/xpath/adapter/traversal.ts +2 -2
  222. package/src/integration/xpath/static-dom/StaticAttribute.ts +6 -5
  223. package/src/integration/xpath/static-dom/StaticDocument.ts +17 -16
  224. package/src/integration/xpath/static-dom/StaticElement.ts +196 -50
  225. package/src/integration/xpath/static-dom/StaticNode.ts +1 -1
  226. package/src/integration/xpath/static-dom/StaticParentNode.ts +22 -0
  227. package/src/integration/xpath/static-dom/staticNodeName.ts +20 -0
  228. package/src/lib/client-reactivity/instance-state/createNodeRangeInstanceState.ts +17 -0
  229. package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +22 -0
  230. package/src/lib/client-reactivity/instance-state/createPrimaryInstanceState.ts +12 -0
  231. package/src/lib/client-reactivity/{submission/createRootSubmissionState.ts → instance-state/createRootInstanceState.ts} +4 -4
  232. package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +31 -0
  233. package/src/lib/client-reactivity/instance-state/createValueNodeInstanceState.ts +21 -0
  234. package/src/lib/client-reactivity/instance-state/prepareInstancePayload.ts +237 -0
  235. package/src/lib/names/UnprefixedXFormsName.ts +12 -0
  236. package/src/lib/reactivity/createInstanceAttachment.ts +212 -0
  237. package/src/lib/reactivity/createInstanceValueState.ts +27 -51
  238. package/src/lib/resource-helpers.ts +33 -0
  239. package/src/parse/XFormDOM.ts +1 -3
  240. package/src/parse/body/BodyDefinition.ts +4 -0
  241. package/src/parse/body/control/UploadControlDefinition.ts +42 -0
  242. package/src/parse/model/BindDefinition.ts +1 -1
  243. package/src/parse/model/BindTypeDefinition.ts +68 -26
  244. package/src/parse/model/ItextTranslationsDefinition.ts +79 -0
  245. package/src/parse/model/LeafNodeDefinition.ts +3 -5
  246. package/src/parse/model/ModelBindMap.ts +0 -5
  247. package/src/parse/model/ModelDefinition.ts +36 -3
  248. package/src/parse/model/NodeDefinition.ts +19 -45
  249. package/src/parse/model/NoteNodeDefinition.ts +4 -3
  250. package/src/parse/model/RangeNodeDefinition.ts +3 -2
  251. package/src/parse/model/RepeatDefinition.ts +382 -0
  252. package/src/parse/model/RootAttributeDefinition.ts +6 -7
  253. package/src/parse/model/RootAttributeMap.ts +15 -10
  254. package/src/parse/model/RootDefinition.ts +17 -19
  255. package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +23 -2
  256. package/src/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.ts +14 -0
  257. package/src/parse/model/SecondaryInstance/defineSecondaryInstance.ts +32 -0
  258. package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +3 -24
  259. package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +33 -86
  260. package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.ts +1 -30
  261. package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +64 -137
  262. package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +9 -7
  263. package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +1 -1
  264. package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +7 -7
  265. package/src/parse/model/{FormSubmissionDefinition.ts → SubmissionDefinition.ts} +2 -2
  266. package/src/parse/model/SubtreeDefinition.ts +4 -5
  267. package/src/parse/model/nodeDefinitionMap.ts +34 -0
  268. package/src/parse/shared/parseInstanceXML.ts +79 -0
  269. package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +45 -130
  270. package/dist/client/EngineConfig.d.ts +0 -79
  271. package/dist/client/submission/SubmissionData.d.ts +0 -7
  272. package/dist/client/submission/SubmissionInstanceFile.d.ts +0 -6
  273. package/dist/client/submission/SubmissionOptions.d.ts +0 -23
  274. package/dist/client/submission/SubmissionResult.d.ts +0 -91
  275. package/dist/client/submission/SubmissionState.d.ts +0 -12
  276. package/dist/client/unsupported/UnsupportedControlNode.d.ts +0 -30
  277. package/dist/client/unsupported/UploadNode.d.ts +0 -9
  278. package/dist/instance/abstract/UnsupportedControl.d.ts +0 -54
  279. package/dist/instance/index.d.ts +0 -8
  280. package/dist/instance/internal-api/ValueContext.d.ts +0 -23
  281. package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +0 -14
  282. package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +0 -32
  283. package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +0 -19
  284. package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +0 -18
  285. package/dist/instance/unsupported/UploadControl.d.ts +0 -6
  286. package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +0 -3
  287. package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +0 -3
  288. package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +0 -4
  289. package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +0 -4
  290. package/dist/lib/client-reactivity/submission/createRootSubmissionState.d.ts +0 -3
  291. package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +0 -3
  292. package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +0 -8
  293. package/dist/lib/reactivity/createValueState.d.ts +0 -40
  294. package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +0 -4
  295. package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +0 -9
  296. package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +0 -8
  297. package/dist/parse/model/RepeatInstanceDefinition.d.ts +0 -17
  298. package/dist/parse/model/RepeatRangeDefinition.d.ts +0 -32
  299. package/dist/parse/model/RepeatTemplateDefinition.d.ts +0 -31
  300. package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +0 -4
  301. package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +0 -7
  302. package/src/client/EngineConfig.ts +0 -84
  303. package/src/client/submission/SubmissionData.ts +0 -12
  304. package/src/client/submission/SubmissionInstanceFile.ts +0 -9
  305. package/src/client/submission/SubmissionOptions.ts +0 -28
  306. package/src/client/submission/SubmissionResult.ts +0 -124
  307. package/src/client/submission/SubmissionState.ts +0 -14
  308. package/src/client/unsupported/UnsupportedControlNode.ts +0 -36
  309. package/src/client/unsupported/UploadNode.ts +0 -14
  310. package/src/instance/abstract/UnsupportedControl.ts +0 -175
  311. package/src/instance/index.ts +0 -55
  312. package/src/instance/internal-api/ValueContext.ts +0 -28
  313. package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +0 -20
  314. package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +0 -43
  315. package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +0 -26
  316. package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +0 -24
  317. package/src/instance/unsupported/UploadControl.ts +0 -9
  318. package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +0 -12
  319. package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +0 -20
  320. package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +0 -17
  321. package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +0 -22
  322. package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +0 -21
  323. package/src/lib/client-reactivity/submission/prepareSubmission.ts +0 -172
  324. package/src/lib/reactivity/createValueState.ts +0 -200
  325. package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +0 -4
  326. package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +0 -42
  327. package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +0 -31
  328. package/src/parse/model/RepeatInstanceDefinition.ts +0 -38
  329. package/src/parse/model/RepeatRangeDefinition.ts +0 -98
  330. package/src/parse/model/RepeatTemplateDefinition.ts +0 -149
  331. package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +0 -4
  332. package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +0 -12
@@ -11,9 +11,11 @@ import type {
11
11
  } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
12
12
  import { XFORMS_XPATH_NODE_RANGE_KIND } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
13
13
  import type { EngineXPathEvaluator } from '../../integration/xpath/EngineXPathEvaluator.ts';
14
+ import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
14
15
  import { createComputedExpression } from '../../lib/reactivity/createComputedExpression.ts';
15
16
  import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
16
17
  import type { AnyNodeDefinition } from '../../parse/model/NodeDefinition.ts';
18
+ import type { DescendantNodeInitOptions } from '../children/DescendantNodeInitOptions.ts';
17
19
  import type { AnyChildNode, AnyParentNode, RepeatRange } from '../hierarchy.ts';
18
20
  import type { EvaluationContext } from '../internal-api/EvaluationContext.ts';
19
21
  import type { RepeatInstance } from '../repeat/RepeatInstance.ts';
@@ -50,6 +52,13 @@ interface DescendantNodeOptions {
50
52
  readonly computeReference?: Accessor<string>;
51
53
  }
52
54
 
55
+ /**
56
+ * @todo Unify constructor signatures of {@link DescendantNode} and its
57
+ * subclasses, which will simplify the branchy logic of child node construction
58
+ * and minimize internal churn as common themes evolve. A good starting point is
59
+ * beginning to form in {@link DescendantNodeInitOptions} (not to be confused
60
+ * with the current module-local {@link DescendantNodeOptions}).
61
+ */
53
62
  export abstract class DescendantNode<
54
63
  Definition extends DescendantNodeDefinition,
55
64
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -128,10 +137,11 @@ export abstract class DescendantNode<
128
137
 
129
138
  constructor(
130
139
  override readonly parent: Parent,
140
+ override readonly instanceNode: StaticElement | null,
131
141
  override readonly definition: Definition,
132
142
  options?: DescendantNodeOptions
133
143
  ) {
134
- super(parent.engineConfig, parent, definition, options);
144
+ super(parent.instanceConfig, parent, instanceNode, definition, options);
135
145
 
136
146
  if (this.isRoot()) {
137
147
  this.root = this;
@@ -142,7 +152,7 @@ export abstract class DescendantNode<
142
152
  const { evaluator } = parent;
143
153
 
144
154
  // See notes on property declaration
145
- if (definition.type === 'repeat-range') {
155
+ if (definition.type === 'repeat') {
146
156
  this[XPathNodeKindKey] = XFORMS_XPATH_NODE_RANGE_KIND;
147
157
  } else {
148
158
  this[XPathNodeKindKey] = 'element';
@@ -4,7 +4,7 @@ import type { BaseNode } from '../../client/BaseNode.ts';
4
4
  import type { NodeAppearances } from '../../client/NodeAppearances.ts';
5
5
  import type { FormNodeID } from '../../client/identity.ts';
6
6
  import type { InstanceNodeType as ClientInstanceNodeType } from '../../client/node-types.ts';
7
- import type { SubmissionState } from '../../client/submission/SubmissionState.ts';
7
+ import type { InstanceState } from '../../client/serialization/InstanceState.ts';
8
8
  import type { NodeValidationState } from '../../client/validation.ts';
9
9
  import type { ActiveLanguage, TextRange } from '../../index.ts';
10
10
  import type { EngineXPathEvaluator } from '../../integration/xpath/EngineXPathEvaluator.ts';
@@ -13,6 +13,8 @@ import type {
13
13
  XFormsXPathPrimaryInstanceNodeKind,
14
14
  } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
15
15
  import type { PrimaryInstanceXPathNode } from '../../integration/xpath/adapter/kind.ts';
16
+ import type { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
17
+ import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
16
18
  import type { MaterializedChildren } from '../../lib/reactivity/materializeCurrentStateChildren.ts';
17
19
  import type { CurrentState } from '../../lib/reactivity/node-state/createCurrentState.ts';
18
20
  import type { EngineState } from '../../lib/reactivity/node-state/createEngineState.ts';
@@ -20,6 +22,7 @@ import type { SharedNodeState } from '../../lib/reactivity/node-state/createShar
20
22
  import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
21
23
  import { createReactiveScope } from '../../lib/reactivity/scope.ts';
22
24
  import type { SimpleAtomicState } from '../../lib/reactivity/types.ts';
25
+ import { createUniqueId } from '../../lib/unique-id.ts';
23
26
  import type { AnyNodeDefinition } from '../../parse/model/NodeDefinition.ts';
24
27
  import type { PrimaryInstance } from '../PrimaryInstance.ts';
25
28
  import type { Root } from '../Root.ts';
@@ -148,7 +151,7 @@ export abstract class InstanceNode<
148
151
 
149
152
  abstract readonly validationState: NodeValidationState;
150
153
 
151
- abstract readonly submissionState: SubmissionState;
154
+ abstract readonly instanceState: InstanceState;
152
155
 
153
156
  // EvaluationContext: instance-global/shared
154
157
  abstract readonly evaluator: EngineXPathEvaluator;
@@ -186,8 +189,9 @@ export abstract class InstanceNode<
186
189
  this as AnyInstanceNode as PrimaryInstanceXPathNode;
187
190
 
188
191
  constructor(
189
- readonly engineConfig: InstanceConfig,
192
+ readonly instanceConfig: InstanceConfig,
190
193
  readonly parent: Parent,
194
+ readonly instanceNode: StaticDocument | StaticElement | null,
191
195
  readonly definition: Definition,
192
196
  options?: InstanceNodeOptions
193
197
  ) {
@@ -208,8 +212,8 @@ export abstract class InstanceNode<
208
212
  this.computeReference = options?.computeReference ?? this.computeChildStepReference;
209
213
 
210
214
  this.scope = options?.scope ?? createReactiveScope();
211
- this.engineConfig = engineConfig;
212
- this.nodeId = nodeID(engineConfig.createUniqueId());
215
+ this.instanceConfig = instanceConfig;
216
+ this.nodeId = nodeID(createUniqueId());
213
217
  this.definition = definition;
214
218
  }
215
219
 
@@ -2,11 +2,12 @@ import { XPathNodeKindKey } from '@getodk/xpath';
2
2
  import type { Accessor } from 'solid-js';
3
3
  import type { BaseValueNode } from '../../client/BaseValueNode.ts';
4
4
  import type { LeafNodeType as ValueNodeType } from '../../client/node-types.ts';
5
- import type { SubmissionState } from '../../client/submission/SubmissionState.ts';
5
+ import type { InstanceState } from '../../client/serialization/InstanceState.ts';
6
6
  import type { AnyViolation, LeafNodeValidationState } from '../../client/validation.ts';
7
7
  import type { ValueType } from '../../client/ValueType.ts';
8
8
  import type { XFormsXPathElement } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
9
- import { createValueNodeSubmissionState } from '../../lib/client-reactivity/submission/createValueNodeSubmissionState.ts';
9
+ import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
10
+ import { createValueNodeInstanceState } from '../../lib/client-reactivity/instance-state/createValueNodeInstanceState.ts';
10
11
  import type {
11
12
  RuntimeValueSetter,
12
13
  RuntimeValueState,
@@ -26,7 +27,7 @@ import type {
26
27
  DecodeInstanceValue,
27
28
  InstanceValueContext,
28
29
  } from '../internal-api/InstanceValueContext.ts';
29
- import type { ClientReactiveSubmittableValueNode } from '../internal-api/submission/ClientReactiveSubmittableValueNode.ts';
30
+ import type { ClientReactiveSerializableValueNode } from '../internal-api/serialization/ClientReactiveSerializableValueNode.ts';
30
31
  import type { ValidationContext } from '../internal-api/ValidationContext.ts';
31
32
  import type { DescendantNodeStateSpec } from './DescendantNode.ts';
32
33
  import { DescendantNode } from './DescendantNode.ts';
@@ -52,7 +53,7 @@ export abstract class ValueNode<
52
53
  EvaluationContext,
53
54
  InstanceValueContext,
54
55
  ValidationContext,
55
- ClientReactiveSubmittableValueNode
56
+ ClientReactiveSerializableValueNode
56
57
  {
57
58
  protected readonly validation: SharedValidationState;
58
59
  protected readonly getInstanceValue: Accessor<string>;
@@ -80,21 +81,20 @@ export abstract class ValueNode<
80
81
  return this.validation.currentState;
81
82
  }
82
83
 
83
- readonly submissionState: SubmissionState;
84
+ readonly instanceState: InstanceState;
84
85
 
85
86
  constructor(
86
87
  parent: GeneralParentNode,
88
+ override readonly instanceNode: StaticLeafElement | null,
87
89
  definition: Definition,
88
90
  codec: ValueCodec<V, RuntimeValue, RuntimeInputValue>
89
91
  ) {
90
- super(parent, definition);
92
+ super(parent, instanceNode, definition);
91
93
 
92
94
  this.valueType = definition.valueType;
93
95
  this.decodeInstanceValue = codec.decodeInstanceValue;
94
96
 
95
- const instanceValueState = createInstanceValueState(this, {
96
- initialValueSource: 'FORM_DEFAULT',
97
- });
97
+ const instanceValueState = createInstanceValueState(this);
98
98
  const valueState = codec.createRuntimeValueState(instanceValueState);
99
99
 
100
100
  const [getInstanceValue] = instanceValueState;
@@ -106,10 +106,8 @@ export abstract class ValueNode<
106
106
  return this.getInstanceValue();
107
107
  };
108
108
  this.valueState = valueState;
109
- this.validation = createValidationState(this, {
110
- clientStateFactory: this.engineConfig.stateFactory,
111
- });
112
- this.submissionState = createValueNodeSubmissionState(this);
109
+ this.validation = createValidationState(this, this.instanceConfig);
110
+ this.instanceState = createValueNodeInstanceState(this);
113
111
  }
114
112
 
115
113
  // ValidationContext
@@ -0,0 +1,69 @@
1
+ import type { Accessor } from 'solid-js';
2
+ import type { InstancePayload } from '../../client/index.ts';
3
+ import type { SimpleAtomicState, SimpleAtomicStateSetter } from '../../lib/reactivity/types.ts';
4
+ import type { InstanceAttachmentContext } from '../internal-api/InstanceAttachmentContext.ts';
5
+ import type { DecodeInstanceValue } from '../internal-api/InstanceValueContext.ts';
6
+ import type { InstanceAttachmentsState } from './InstanceAttachmentsState.ts';
7
+
8
+ export type InstanceAttachmentFileName = string;
9
+ export type InstanceAttachmentRuntimeValue = File | null;
10
+
11
+ export interface InstanceAttachmentOptions {
12
+ readonly getFileName: Accessor<InstanceAttachmentFileName | null>;
13
+ readonly getInstanceValue: Accessor<InstanceAttachmentFileName>;
14
+ readonly decodeInstanceValue: DecodeInstanceValue;
15
+
16
+ readonly getValue: Accessor<InstanceAttachmentRuntimeValue>;
17
+ readonly setValue: SimpleAtomicStateSetter<InstanceAttachmentRuntimeValue>;
18
+ readonly valueState: SimpleAtomicState<InstanceAttachmentRuntimeValue>;
19
+ }
20
+
21
+ export class InstanceAttachment {
22
+ /**
23
+ * 1. Creates {@link InstanceAttachment | attachment state} from
24
+ * {@link InstanceAttachmentOptions}
25
+ * 2. Registers that attachment state in an instance-global
26
+ * {@link InstanceAttachmentsState} entry
27
+ *
28
+ * This allows an instance to:
29
+ *
30
+ * - Produce distinct file names for each attachment
31
+ * - Track all attachments so they can be serialized in an
32
+ * {@link InstancePayload}
33
+ */
34
+ static init(
35
+ context: InstanceAttachmentContext,
36
+ options: InstanceAttachmentOptions
37
+ ): InstanceAttachment {
38
+ const attachment = new this(options);
39
+ const { attachments } = context.rootDocument;
40
+
41
+ attachments.set(context, attachment);
42
+
43
+ return attachment;
44
+ }
45
+
46
+ /**
47
+ * This property isn't used at runtime. It causes TypeScript to treat
48
+ * {@link InstanceAttachment} as a nominal type, ensuring
49
+ * {@link InstanceAttachment.init} is called to instantiate it.
50
+ */
51
+ protected readonly _ = null;
52
+
53
+ readonly getFileName: Accessor<InstanceAttachmentFileName | null>;
54
+ readonly getInstanceValue: Accessor<InstanceAttachmentFileName>;
55
+ readonly decodeInstanceValue: DecodeInstanceValue;
56
+
57
+ readonly getValue: Accessor<InstanceAttachmentRuntimeValue>;
58
+ readonly setValue: SimpleAtomicStateSetter<InstanceAttachmentRuntimeValue>;
59
+ readonly valueState: SimpleAtomicState<InstanceAttachmentRuntimeValue>;
60
+
61
+ private constructor(options: InstanceAttachmentOptions) {
62
+ this.getFileName = options.getFileName;
63
+ this.getInstanceValue = options.getInstanceValue;
64
+ this.decodeInstanceValue = options.decodeInstanceValue;
65
+ this.getValue = options.getValue;
66
+ this.setValue = options.setValue;
67
+ this.valueState = options.valueState;
68
+ }
69
+ }
@@ -0,0 +1,18 @@
1
+ import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
2
+ import type { InstanceAttachmentMap } from '../input/InstanceAttachmentMap.ts';
3
+ import type { InstanceAttachmentContext } from '../internal-api/InstanceAttachmentContext.ts';
4
+ import type { InstanceAttachment, InstanceAttachmentRuntimeValue } from './InstanceAttachment.ts';
5
+
6
+ export class InstanceAttachmentsState extends Map<InstanceAttachmentContext, InstanceAttachment> {
7
+ constructor(private readonly sourceAttachments: InstanceAttachmentMap | null = null) {
8
+ super();
9
+ }
10
+
11
+ getInitialFileValue(instanceNode: StaticLeafElement | null): InstanceAttachmentRuntimeValue {
12
+ if (instanceNode == null) {
13
+ return null;
14
+ }
15
+
16
+ return this.sourceAttachments?.get(instanceNode.value) ?? null;
17
+ }
18
+ }
@@ -0,0 +1,35 @@
1
+ import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
2
+ import type { ChildNodeDefinition } from '../../parse/model/NodeDefinition.ts';
3
+ import type { DescendantNode } from '../abstract/DescendantNode.ts';
4
+ import type { childrenInitOptions } from './childrenInitOptions.ts';
5
+
6
+ /**
7
+ * @todo We could pretty significantly simplify downstream child node
8
+ * construction logic, if we break this down into a tagged union (essentially
9
+ * moving the branchy type refinement aspects up the stack, probably trimming
10
+ * the construction logic itself down to a switch statement). At which point,
11
+ * it'd also probably be easier to reason about each of those constructors
12
+ * accepting input exactly as it's represented as a member of this hypothetical
13
+ * tagged union. Something like this:
14
+ *
15
+ * - Revise each concrete {@link DescendantNode} class to accept an options-like
16
+ * object suitable for its construction, each respectively defined by an
17
+ * interface whose name is consistent with that node
18
+ * - Update this type to be a union of those interfaces
19
+ * - Implement that in {@link childrenInitOptions}
20
+ * - Update downstream construction to switch over whatever narrows the union
21
+ * - Bonus points: revise each concrete {@link DescendantNode} to use a common
22
+ * constructor API (i.e. a static `from` method, since several such classes
23
+ * already have private constructors). Then downstream isn't even a switch
24
+ * statement, it's just a lookup table.
25
+ *
26
+ * @todo As of this commit, and as now mentioned on {@link DescendantNode}, and
27
+ * as discussed in
28
+ * {@link https://github.com/getodk/web-forms/pull/352#discussion_r2008237762}:
29
+ * this interface is intended as an intermediate step toward these goals.
30
+ */
31
+ export interface DescendantNodeInitOptions {
32
+ readonly childNodeset: string;
33
+ readonly definition: ChildNodeDefinition;
34
+ readonly instanceNodes: readonly StaticElement[];
35
+ }
@@ -1,34 +1,35 @@
1
1
  import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
2
- import type { GroupDefinition } from '../client/GroupNode.ts';
3
- import type { InputDefinition } from '../client/InputNode.ts';
4
- import type { ModelValueDefinition } from '../client/ModelValueNode.ts';
5
- import type { SelectDefinition } from '../client/SelectNode.ts';
6
- import type { SubtreeDefinition } from '../client/SubtreeNode.ts';
7
- import type { TriggerNodeDefinition } from '../client/TriggerNode.ts';
8
- import type { RankDefinition } from '../client/RankNode.ts';
9
- import type { UploadNodeDefinition } from '../client/unsupported/UploadNode.ts';
10
- import { ErrorProductionDesignPendingError } from '../error/ErrorProductionDesignPendingError.ts';
11
- import type { LeafNodeDefinition } from '../parse/model/LeafNodeDefinition.ts';
12
- import { NoteNodeDefinition } from '../parse/model/NoteNodeDefinition.ts';
2
+ import type { GroupDefinition } from '../../client/GroupNode.ts';
3
+ import type { InputDefinition } from '../../client/InputNode.ts';
4
+ import type { ModelValueDefinition } from '../../client/ModelValueNode.ts';
5
+ import type { RankDefinition } from '../../client/RankNode.ts';
6
+ import type { SelectDefinition } from '../../client/SelectNode.ts';
7
+ import type { SubtreeDefinition } from '../../client/SubtreeNode.ts';
8
+ import type { TriggerNodeDefinition } from '../../client/TriggerNode.ts';
9
+ import type { UploadDefinition } from '../../client/UploadNode.ts';
10
+ import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
11
+ import type { LeafNodeDefinition } from '../../parse/model/LeafNodeDefinition.ts';
12
+ import { NoteNodeDefinition } from '../../parse/model/NoteNodeDefinition.ts';
13
13
  import type {
14
14
  AnyRangeNodeDefinition,
15
15
  RangeLeafNodeDefinition,
16
- } from '../parse/model/RangeNodeDefinition.ts';
17
- import { RangeNodeDefinition } from '../parse/model/RangeNodeDefinition.ts';
18
- import type { SubtreeDefinition as ModelSubtreeDefinition } from '../parse/model/SubtreeDefinition.ts';
19
- import { Group } from './Group.ts';
20
- import type { GeneralChildNode, GeneralParentNode } from './hierarchy.ts';
21
- import { InputControl } from './InputControl.ts';
22
- import { ModelValue } from './ModelValue.ts';
23
- import { Note } from './Note.ts';
24
- import { RangeControl } from './RangeControl.ts';
25
- import { RepeatRangeControlled } from './repeat/RepeatRangeControlled.ts';
26
- import { RepeatRangeUncontrolled } from './repeat/RepeatRangeUncontrolled.ts';
27
- import { SelectControl } from './SelectControl.ts';
28
- import { Subtree } from './Subtree.ts';
29
- import { TriggerControl } from './TriggerControl.ts';
30
- import { RankControl } from './RankControl.ts';
31
- import { UploadControl } from './unsupported/UploadControl.ts';
16
+ } from '../../parse/model/RangeNodeDefinition.ts';
17
+ import { RangeNodeDefinition } from '../../parse/model/RangeNodeDefinition.ts';
18
+ import type { SubtreeDefinition as ModelSubtreeDefinition } from '../../parse/model/SubtreeDefinition.ts';
19
+ import { Group } from '../Group.ts';
20
+ import type { GeneralChildNode, GeneralParentNode } from '../hierarchy.ts';
21
+ import { InputControl } from '../InputControl.ts';
22
+ import { ModelValue } from '../ModelValue.ts';
23
+ import { Note } from '../Note.ts';
24
+ import { RangeControl } from '../RangeControl.ts';
25
+ import { RankControl } from '../RankControl.ts';
26
+ import { RepeatRangeControlled } from '../repeat/RepeatRangeControlled.ts';
27
+ import { RepeatRangeUncontrolled } from '../repeat/RepeatRangeUncontrolled.ts';
28
+ import { SelectControl } from '../SelectControl.ts';
29
+ import { Subtree } from '../Subtree.ts';
30
+ import { TriggerControl } from '../TriggerControl.ts';
31
+ import { UploadControl } from '../UploadControl.ts';
32
+ import { childrenInitOptions } from './childrenInitOptions.ts';
32
33
 
33
34
  const isSubtreeDefinition = (
34
35
  definition: ModelSubtreeDefinition
@@ -36,9 +37,6 @@ const isSubtreeDefinition = (
36
37
  return definition.bodyElement == null;
37
38
  };
38
39
 
39
- // prettier-ignore
40
- type AnyUnsupportedControlDefinition = UploadNodeDefinition;
41
-
42
40
  // prettier-ignore
43
41
  type ControlNodeDefinition =
44
42
  // eslint-disable-next-line @typescript-eslint/sort-type-constituents
@@ -47,7 +45,7 @@ type ControlNodeDefinition =
47
45
  | SelectDefinition
48
46
  | RankDefinition
49
47
  | TriggerNodeDefinition
50
- | AnyUnsupportedControlDefinition;
48
+ | UploadDefinition;
51
49
 
52
50
  type AnyLeafNodeDefinition = ControlNodeDefinition | ModelValueDefinition;
53
51
 
@@ -122,77 +120,83 @@ const isTriggerNodeDefinition = (
122
120
 
123
121
  const isUploadNodeDefinition = (
124
122
  definition: ControlNodeDefinition
125
- ): definition is UploadNodeDefinition => {
123
+ ): definition is UploadDefinition => {
126
124
  return definition.bodyElement.type === 'upload';
127
125
  };
128
126
 
129
127
  export const buildChildren = (parent: GeneralParentNode): GeneralChildNode[] => {
130
- const { children } = parent.definition;
128
+ const { children } = childrenInitOptions(parent);
129
+
130
+ return children.map(({ instanceNodes, definition }): GeneralChildNode => {
131
+ const [instanceNode = null] = instanceNodes;
131
132
 
132
- return children.map((child): GeneralChildNode => {
133
- switch (child.type) {
133
+ switch (definition.type) {
134
134
  case 'subtree': {
135
- if (isSubtreeDefinition(child)) {
136
- return new Subtree(parent, child);
135
+ if (isSubtreeDefinition(definition)) {
136
+ return new Subtree(parent, instanceNode, definition);
137
137
  }
138
138
 
139
139
  // TODO: it'd be good to be able to do without this type assertion. The
140
140
  // only distinction between the types is whether `bodyElement` is
141
141
  // `null`, but for some reason that's insufficient to narrow the union.
142
- return new Group(parent, child as GroupDefinition);
142
+ return new Group(parent, instanceNode, definition as GroupDefinition);
143
143
  }
144
144
 
145
- case 'repeat-range': {
146
- if (child.isControlled()) {
147
- return new RepeatRangeControlled(parent, child);
145
+ case 'repeat': {
146
+ if (definition.isControlled()) {
147
+ return new RepeatRangeControlled(parent, instanceNodes, definition);
148
148
  }
149
149
 
150
- return new RepeatRangeUncontrolled(parent, child);
150
+ return new RepeatRangeUncontrolled(parent, instanceNodes, definition);
151
151
  }
152
152
 
153
153
  case 'leaf-node': {
154
- if (child instanceof NoteNodeDefinition) {
155
- return new Note(parent, child);
154
+ if (instanceNode != null && !instanceNode.isLeafElement()) {
155
+ throw new ErrorProductionDesignPendingError();
156
+ }
157
+
158
+ if (definition instanceof NoteNodeDefinition) {
159
+ return new Note(parent, instanceNode, definition);
156
160
  }
157
161
 
158
162
  // More specific type helps with narrowing below
159
- const leafChild: AnyLeafNodeDefinition = child;
163
+ const leafChild: AnyLeafNodeDefinition = definition;
160
164
 
161
165
  if (isModelValueDefinition(leafChild)) {
162
- return ModelValue.from(parent, leafChild);
166
+ return ModelValue.from(parent, instanceNode, leafChild);
163
167
  }
164
168
 
165
169
  if (isInputDefinition(leafChild)) {
166
- return InputControl.from(parent, leafChild);
170
+ return InputControl.from(parent, instanceNode, leafChild);
167
171
  }
168
172
 
169
173
  if (isSelectDefinition(leafChild)) {
170
- return SelectControl.from(parent, leafChild);
174
+ return SelectControl.from(parent, instanceNode, leafChild);
171
175
  }
172
176
 
173
177
  if (isRankDefinition(leafChild)) {
174
- return RankControl.from(parent, leafChild);
178
+ return RankControl.from(parent, instanceNode, leafChild);
175
179
  }
176
180
 
177
181
  if (isTriggerNodeDefinition(leafChild)) {
178
- return TriggerControl.from(parent, leafChild);
182
+ return TriggerControl.from(parent, instanceNode, leafChild);
179
183
  }
180
184
 
181
185
  if (isRangeLeafNodeDefinition(leafChild)) {
182
186
  assertRangeNodeDefinition(leafChild);
183
187
 
184
- return RangeControl.from(parent, leafChild);
188
+ return RangeControl.from(parent, instanceNode, leafChild);
185
189
  }
186
190
 
187
191
  if (isUploadNodeDefinition(leafChild)) {
188
- return new UploadControl(parent, leafChild);
192
+ return UploadControl.from(parent, instanceNode, leafChild);
189
193
  }
190
194
 
191
195
  throw new UnreachableError(leafChild);
192
196
  }
193
197
 
194
198
  default: {
195
- throw new UnreachableError(child);
199
+ throw new UnreachableError(definition);
196
200
  }
197
201
  }
198
202
  });
@@ -0,0 +1,117 @@
1
+ import type { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
2
+ import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
3
+ import type { ModelDefinition } from '../../parse/model/ModelDefinition.ts';
4
+ import type {
5
+ AnyNodeDefinition,
6
+ ChildNodeDefinition,
7
+ NodeDefinition,
8
+ } from '../../parse/model/NodeDefinition.ts';
9
+ import type { InstanceNode } from '../abstract/InstanceNode.ts';
10
+ import type { GeneralParentNode } from '../hierarchy.ts';
11
+ import type { DescendantNodeInitOptions } from './DescendantNodeInitOptions.ts';
12
+ import { normalizeChildInitOptions } from './normalizeChildInitOptions.ts';
13
+
14
+ /**
15
+ * Child nodesets are collected from the {@link parent}'s
16
+ * {@link NodeDefinition.template}, ensuring that we produce
17
+ * {@link InstanceNode}s for every **model-defined** node, even if a
18
+ * corresponding node was not serialized in a {@link parent.instanceNode}.
19
+ *
20
+ * In other words, by referencing the model-defined template, we are able to
21
+ * reproduce nodes which were omitted as non-relevant in a prior serialization
22
+ * and/or submission.
23
+ *
24
+ * @todo Since we're building an instance node's children from the nodesets of
25
+ * the model-defined node's children, we are _implicitly dropping_ any excess
26
+ * nodes from non-model instance data. That's probably the right behavior, but
27
+ * we may want to warn for such nodes if/when we do drop them.
28
+ */
29
+ const collectModelChildNodesets = (parentTemplate: StaticElement): readonly string[] => {
30
+ const nodesets = parentTemplate.childElements.map(({ nodeset }) => {
31
+ return nodeset;
32
+ });
33
+
34
+ return Array.from(new Set(nodesets));
35
+ };
36
+
37
+ type InstanceNodesByNodeset = ReadonlyMap<string, readonly [StaticElement, ...StaticElement[]]>;
38
+
39
+ const groupChildElementsByNodeset = (
40
+ parent: StaticDocument | StaticElement
41
+ ): InstanceNodesByNodeset => {
42
+ const result = new Map<string, [StaticElement, ...StaticElement[]]>();
43
+
44
+ for (const child of parent.childElements) {
45
+ const { nodeset } = child;
46
+ const group = result.get(nodeset);
47
+
48
+ if (group == null) {
49
+ result.set(nodeset, [child]);
50
+ } else {
51
+ group.push(child);
52
+ }
53
+ }
54
+
55
+ return result;
56
+ };
57
+
58
+ type AssertChildNodeDefinition = (
59
+ definition: AnyNodeDefinition,
60
+ childNodeset: string
61
+ ) => asserts definition is ChildNodeDefinition;
62
+
63
+ const assertChildNodeDefinition: AssertChildNodeDefinition = (definition, childNodeset) => {
64
+ if (definition.type === 'root') {
65
+ throw new Error(`Unexpected root definition for child nodeset: ${childNodeset}`);
66
+ }
67
+ };
68
+
69
+ export interface ChildrenInitOptions {
70
+ readonly parent: GeneralParentNode;
71
+ readonly model: ModelDefinition;
72
+ readonly children: readonly DescendantNodeInitOptions[];
73
+ }
74
+
75
+ export const childrenInitOptions = (parent: GeneralParentNode): ChildrenInitOptions => {
76
+ const { model } = parent.rootDocument;
77
+ const childNodesets = collectModelChildNodesets(parent.definition.template);
78
+
79
+ let instanceChildren: InstanceNodesByNodeset | null;
80
+
81
+ if (parent.instanceNode == null) {
82
+ instanceChildren = null;
83
+ } else {
84
+ instanceChildren = groupChildElementsByNodeset(parent.instanceNode);
85
+ }
86
+
87
+ const children = childNodesets.map((childNodeset) => {
88
+ const definition = model.getNodeDefinition(childNodeset);
89
+
90
+ assertChildNodeDefinition(definition, childNodeset);
91
+
92
+ /**
93
+ * Get children of the target nodeset from {@link parent.instanceNode}, if
94
+ * that node exists, and if children with that nodeset exist.
95
+ *
96
+ * If either does not exist (e.g. it was omitted as non-relevant in a prior
97
+ * serialization), we continue to reference model-defined templates as we
98
+ * recurse down the {@link InstanceNode} subtree.
99
+ *
100
+ * @see {@link childNodesets}
101
+ */
102
+ const instanceNodes = instanceChildren?.get(childNodeset) ?? [];
103
+
104
+ return {
105
+ childNodeset,
106
+ definition,
107
+ instanceNodes,
108
+ };
109
+ });
110
+ const baseResult: ChildrenInitOptions = {
111
+ parent,
112
+ model,
113
+ children,
114
+ };
115
+
116
+ return normalizeChildInitOptions(baseResult);
117
+ };