@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
@@ -0,0 +1,332 @@
1
+ import {
2
+ OPENROSA_XFORMS_NAMESPACE_URI,
3
+ XFORMS_NAMESPACE_URI,
4
+ } from '@getodk/common/constants/xmlns.ts';
5
+ import type { GroupDefinition } from '../../client/GroupNode.ts';
6
+ import type { SubtreeDefinition } from '../../client/SubtreeNode.ts';
7
+ import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
8
+ import { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
9
+ import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
10
+ import { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
11
+ import type { NamespaceURL } from '../../lib/names/NamespaceURL.ts';
12
+ import type { QualifiedName } from '../../lib/names/QualifiedName.ts';
13
+ import { LeafNodeDefinition } from '../../parse/model/LeafNodeDefinition.ts';
14
+ import type { SubtreeDefinition as ModelSubtreeDefinition } from '../../parse/model/SubtreeDefinition.ts';
15
+ import type { XFormDOM } from '../../parse/XFormDOM.ts';
16
+ import type { Group } from '../Group.ts';
17
+ import type { GeneralParentNode } from '../hierarchy.ts';
18
+ import type { PrimaryInstance } from '../PrimaryInstance.ts';
19
+ import type { Root } from '../Root.ts';
20
+ import type { Subtree } from '../Subtree.ts';
21
+ import type { ChildrenInitOptions } from './childrenInitOptions.ts';
22
+ import type { DescendantNodeInitOptions } from './DescendantNodeInitOptions.ts';
23
+
24
+ const META_LOCAL_NAME = 'meta';
25
+ const INSTANCE_ID_LOCAL_NAME = 'instanceID';
26
+ const DEPRECATED_ID_LOCAL_NAME = 'deprecatedID';
27
+
28
+ type MetaLocalName = typeof META_LOCAL_NAME;
29
+
30
+ const META_NAMESPACE_URIS = [OPENROSA_XFORMS_NAMESPACE_URI, XFORMS_NAMESPACE_URI] as const;
31
+
32
+ type MetaNamespaceURIValue = (typeof META_NAMESPACE_URIS)[number];
33
+
34
+ interface MetaNamespaceURI extends NamespaceURL {
35
+ readonly href: MetaNamespaceURIValue;
36
+ }
37
+
38
+ interface MetaNamespacedName extends QualifiedName {
39
+ readonly namespaceURI: MetaNamespaceURI;
40
+ }
41
+
42
+ const isMetaNamespacedName = (
43
+ qualifiedName: QualifiedName
44
+ ): qualifiedName is MetaNamespacedName => {
45
+ const namespaceURI = qualifiedName.namespaceURI?.href;
46
+
47
+ return (
48
+ namespaceURI != null && META_NAMESPACE_URIS.includes(namespaceURI as MetaNamespaceURIValue)
49
+ );
50
+ };
51
+
52
+ interface MetaName extends MetaNamespacedName {
53
+ readonly localName: MetaLocalName;
54
+ }
55
+
56
+ const isMetaName = (qualifiedName: QualifiedName): qualifiedName is MetaName => {
57
+ return isMetaNamespacedName(qualifiedName) && qualifiedName.localName === META_LOCAL_NAME;
58
+ };
59
+
60
+ const isDirectRootDescendant = (parent: GeneralParentNode) => {
61
+ return parent.parent === parent.root;
62
+ };
63
+
64
+ interface BaseMetaDefinition {
65
+ readonly qualifiedName: MetaName;
66
+ }
67
+
68
+ const isBaseMetaDefinition = <T extends ModelSubtreeDefinition>(
69
+ definition: T
70
+ ): definition is BaseMetaDefinition & T => {
71
+ return isMetaName(definition.qualifiedName);
72
+ };
73
+
74
+ interface MetaSubtreeDefinition extends SubtreeDefinition {
75
+ readonly qualifiedName: MetaName;
76
+ }
77
+
78
+ interface MetaSubtree extends Subtree {
79
+ readonly parent: Root;
80
+ readonly definition: MetaSubtreeDefinition;
81
+ }
82
+
83
+ interface MetaGroupDefinition extends GroupDefinition {
84
+ readonly qualifiedName: MetaName;
85
+ }
86
+
87
+ interface MetaGroup extends Group {
88
+ readonly parent: Root;
89
+ readonly definition: MetaGroupDefinition;
90
+ }
91
+
92
+ type MetaSubroot = MetaGroup | MetaSubtree;
93
+
94
+ interface MetaSubrootInitOptions extends ChildrenInitOptions {
95
+ readonly parent: MetaGroup | MetaSubtree;
96
+ }
97
+
98
+ const isMetaSubroot = (options: ChildrenInitOptions): options is MetaSubrootInitOptions => {
99
+ const { nodeType } = options.parent;
100
+
101
+ return (
102
+ (nodeType === 'subtree' || nodeType === 'group') &&
103
+ isDirectRootDescendant(options.parent) &&
104
+ isBaseMetaDefinition(options.parent.definition)
105
+ );
106
+ };
107
+
108
+ interface EditModeInstance extends PrimaryInstance {
109
+ readonly initializationMode: 'edit';
110
+ }
111
+
112
+ const isEditModeInstance = (
113
+ primaryInstance: PrimaryInstance
114
+ ): primaryInstance is EditModeInstance => {
115
+ return primaryInstance.initializationMode === 'edit';
116
+ };
117
+
118
+ interface EditModeInstanceDescendant {
119
+ readonly rootDocument: EditModeInstance;
120
+ }
121
+
122
+ type EditModeMetaSubroot = EditModeInstanceDescendant & MetaSubroot;
123
+
124
+ interface EditModeMetaSubrootInitOptions extends MetaSubrootInitOptions {
125
+ readonly parent: EditModeMetaSubroot;
126
+ }
127
+
128
+ const isEditModeMetaSubroot = (
129
+ subroot: MetaSubrootInitOptions
130
+ ): subroot is EditModeMetaSubrootInitOptions => {
131
+ return isEditModeInstance(subroot.parent.rootDocument);
132
+ };
133
+
134
+ interface LeafNodeInitOptions extends DescendantNodeInitOptions {
135
+ readonly instanceNodes: readonly [StaticLeafElement];
136
+ }
137
+
138
+ const isLeafNodeInitOptions = (
139
+ options: DescendantNodeInitOptions
140
+ ): options is LeafNodeInitOptions => {
141
+ const { instanceNodes } = options;
142
+ const [instanceNode, ...rest] = instanceNodes;
143
+
144
+ return instanceNode != null && rest.length === 0 && instanceNode.isLeafElement();
145
+ };
146
+
147
+ type MetaLeafChildEntry = readonly [index: number, child: LeafNodeInitOptions];
148
+
149
+ const findMetaLeafChild = (
150
+ subroot: MetaSubrootInitOptions,
151
+ localName: string
152
+ ): MetaLeafChildEntry | null => {
153
+ const metaName = subroot.parent.definition.qualifiedName satisfies MetaName;
154
+ const namespaceURI = metaName.namespaceURI.href satisfies MetaNamespaceURIValue;
155
+
156
+ const result = Array.from(subroot.children.entries()).find(
157
+ (entry): entry is [number, LeafNodeInitOptions] => {
158
+ const [, child] = entry;
159
+
160
+ if (!isLeafNodeInitOptions(child)) {
161
+ return false;
162
+ }
163
+
164
+ const [instanceNode] = child.instanceNodes;
165
+ const { qualifiedName } = instanceNode;
166
+
167
+ return (
168
+ qualifiedName.localName === localName && qualifiedName.namespaceURI?.href === namespaceURI
169
+ );
170
+ }
171
+ );
172
+
173
+ return result ?? null;
174
+ };
175
+
176
+ const getInstanceIDValue = (subroot: MetaSubrootInitOptions): string | null => {
177
+ const [, child = null] = findMetaLeafChild(subroot, INSTANCE_ID_LOCAL_NAME) ?? [];
178
+
179
+ if (child == null) {
180
+ return null;
181
+ }
182
+
183
+ const [instanceIDNode] = child.instanceNodes;
184
+
185
+ return instanceIDNode.value satisfies string;
186
+ };
187
+
188
+ type AssertStaticLeafElement = (element: StaticElement) => asserts element is StaticLeafElement;
189
+
190
+ const assertStaticLeafElement: AssertStaticLeafElement = (element) => {
191
+ if (!element.isLeafElement()) {
192
+ throw new ErrorProductionDesignPendingError(
193
+ `Expected a leaf element, got a non-leaf element at nodeset: ${element.nodeset}`
194
+ );
195
+ }
196
+ };
197
+
198
+ /**
199
+ * @todo this name and signature are general, for the same reasons as the TODO
200
+ * on {@link populateDeprecatedID}.
201
+ */
202
+ const buildMetaValueElement = (
203
+ subroot: MetaSubrootInitOptions,
204
+ localName: string,
205
+ value: string
206
+ ): StaticLeafElement => {
207
+ const { qualifiedName, nodeset } = subroot.parent.definition;
208
+ const { namespaceURI, prefix } = qualifiedName;
209
+ const { root } = new StaticDocument({
210
+ documentRoot: {
211
+ name: {
212
+ namespaceURI,
213
+ prefix,
214
+ localName,
215
+ },
216
+ children: [value],
217
+ },
218
+ nodesetPrefix: nodeset,
219
+ });
220
+
221
+ assertStaticLeafElement(root);
222
+
223
+ return root;
224
+ };
225
+
226
+ const buildDeprecatedIDDefinition = (
227
+ subroot: EditModeMetaSubrootInitOptions,
228
+ instanceNode: StaticLeafElement
229
+ ): LeafNodeDefinition => {
230
+ const nodeset = instanceNode.nodeset;
231
+ const bind = subroot.model.binds.getOrCreateBindDefinition(nodeset);
232
+
233
+ return new LeafNodeDefinition(subroot.parent.definition, bind, null, instanceNode);
234
+ };
235
+
236
+ const buildDeprecatedID = (
237
+ subroot: EditModeMetaSubrootInitOptions,
238
+ value: string
239
+ ): LeafNodeInitOptions => {
240
+ const instanceNode = buildMetaValueElement(subroot, DEPRECATED_ID_LOCAL_NAME, value);
241
+ const definition = buildDeprecatedIDDefinition(subroot, instanceNode);
242
+
243
+ return {
244
+ childNodeset: instanceNode.nodeset,
245
+ definition,
246
+ instanceNodes: [instanceNode],
247
+ };
248
+ };
249
+
250
+ const updateDeprecatedID = (
251
+ subroot: EditModeMetaSubrootInitOptions,
252
+ child: LeafNodeInitOptions,
253
+ value: string
254
+ ): LeafNodeInitOptions => {
255
+ const instanceNode = buildMetaValueElement(subroot, DEPRECATED_ID_LOCAL_NAME, value);
256
+
257
+ return {
258
+ childNodeset: child.childNodeset,
259
+ definition: child.definition,
260
+ instanceNodes: [instanceNode],
261
+ };
262
+ };
263
+
264
+ /**
265
+ * Should be: values.with(index, value)
266
+ *
267
+ * @todo update tsconfig.json `lib` throughout project!
268
+ */
269
+ const replace = <T>(values: readonly T[], index: number, value: T): readonly T[] => {
270
+ const results = values.slice();
271
+
272
+ results.splice(index, 1, value);
273
+
274
+ return results;
275
+ };
276
+
277
+ const replaceOrConcat = <T>(values: readonly T[], index: number | null, value: T): readonly T[] => {
278
+ if (index == null) {
279
+ return values.concat(value);
280
+ }
281
+
282
+ return replace(values, index, value);
283
+ };
284
+
285
+ /**
286
+ * @todo Whenever we have bandwidth to start migrating away from DOM usage in
287
+ * {@link XFormDOM}, this is a good place to start for logic equivalent to the
288
+ * hacky normalization for `instanceID`.
289
+ */
290
+ const populateDeprecatedID = (
291
+ subroot: EditModeMetaSubrootInitOptions
292
+ ): EditModeMetaSubrootInitOptions => {
293
+ const value = getInstanceIDValue(subroot);
294
+
295
+ if (value == null) {
296
+ return subroot;
297
+ }
298
+
299
+ const [index, currentDeprecatedID] = findMetaLeafChild(subroot, DEPRECATED_ID_LOCAL_NAME) ?? [
300
+ null,
301
+ ];
302
+
303
+ let deprecatedID: LeafNodeInitOptions;
304
+
305
+ if (currentDeprecatedID == null) {
306
+ deprecatedID = buildDeprecatedID(subroot, value);
307
+ } else {
308
+ deprecatedID = updateDeprecatedID(subroot, currentDeprecatedID, value);
309
+ }
310
+
311
+ return {
312
+ model: subroot.model,
313
+ parent: subroot.parent,
314
+ children: replaceOrConcat(subroot.children, index, deprecatedID),
315
+ };
316
+ };
317
+
318
+ const normalizeMetaSubroot = (subroot: MetaSubrootInitOptions): MetaSubrootInitOptions => {
319
+ if (isEditModeMetaSubroot(subroot)) {
320
+ return populateDeprecatedID(subroot);
321
+ }
322
+
323
+ return subroot;
324
+ };
325
+
326
+ export const normalizeChildInitOptions = (options: ChildrenInitOptions): ChildrenInitOptions => {
327
+ if (isMetaSubroot(options)) {
328
+ return normalizeMetaSubroot(options);
329
+ }
330
+
331
+ return options;
332
+ };
@@ -4,6 +4,7 @@ import type { AnyModelValue } from './ModelValue.ts';
4
4
  import type { AnyNote } from './Note.ts';
5
5
  import type { PrimaryInstance } from './PrimaryInstance.ts';
6
6
  import type { AnyRangeControl } from './RangeControl.ts';
7
+ import type { RankControl } from './RankControl.ts';
7
8
  import type { RepeatInstance } from './repeat/RepeatInstance.ts';
8
9
  import type { RepeatRangeControlled } from './repeat/RepeatRangeControlled.ts';
9
10
  import type { RepeatRangeUncontrolled } from './repeat/RepeatRangeUncontrolled.ts';
@@ -11,14 +12,10 @@ import type { Root } from './Root.ts';
11
12
  import type { SelectControl } from './SelectControl.ts';
12
13
  import type { Subtree } from './Subtree.ts';
13
14
  import type { TriggerControl } from './TriggerControl.ts';
14
- import type { RankControl } from './RankControl.ts';
15
- import type { UploadControl } from './unsupported/UploadControl.ts';
15
+ import type { UploadControl } from './UploadControl.ts';
16
16
 
17
17
  export type RepeatRange = RepeatRangeControlled | RepeatRangeUncontrolled;
18
18
 
19
- // prettier-ignore
20
- export type AnyUnsupportedControl = UploadControl;
21
-
22
19
  // prettier-ignore
23
20
  export type AnyNode =
24
21
  // eslint-disable-next-line @typescript-eslint/sort-type-constituents
@@ -35,7 +32,7 @@ export type AnyNode =
35
32
  | RankControl
36
33
  | SelectControl
37
34
  | TriggerControl
38
- | AnyUnsupportedControl;
35
+ | UploadControl;
39
36
 
40
37
  // prettier-ignore
41
38
  export type AnyParentNode =
@@ -70,7 +67,7 @@ export type AnyChildNode =
70
67
  | RankControl
71
68
  | SelectControl
72
69
  | TriggerControl
73
- | AnyUnsupportedControl;
70
+ | UploadControl;
74
71
 
75
72
  // prettier-ignore
76
73
  export type GeneralChildNode =
@@ -85,7 +82,7 @@ export type GeneralChildNode =
85
82
  | RankControl
86
83
  | SelectControl
87
84
  | TriggerControl
88
- | AnyUnsupportedControl;
85
+ | UploadControl;
89
86
 
90
87
  // prettier-ignore
91
88
  export type AnyValueNode =
@@ -97,4 +94,4 @@ export type AnyValueNode =
97
94
  | RankControl
98
95
  | SelectControl
99
96
  | TriggerControl
100
- | AnyUnsupportedControl;
97
+ | UploadControl;
@@ -0,0 +1,108 @@
1
+ import { getBlobText } from '@getodk/common/lib/web-compat/blob.ts';
2
+ import { INSTANCE_FILE_NAME } from '../../client/constants.ts';
3
+ import type {
4
+ EditFormInstanceInput,
5
+ ResolvableFormInstanceInput,
6
+ } from '../../client/form/EditFormInstance.ts';
7
+ import type { InstanceData } from '../../client/serialization/InstanceData.ts';
8
+ import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
9
+ import type { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
10
+ import type { ModelDefinition } from '../../parse/model/ModelDefinition.ts';
11
+ import { parseInstanceXML } from '../../parse/shared/parseInstanceXML.ts';
12
+ import type { XFormDOM } from '../../parse/XFormDOM.ts';
13
+ import { InstanceAttachmentMap } from './InstanceAttachmentMap.ts';
14
+
15
+ export type InitialInstanceStateSources = readonly [InstanceData, ...InstanceData[]];
16
+
17
+ interface InitialInstanceStateOptions {
18
+ readonly instanceXML: string;
19
+ readonly attachments: InstanceAttachmentMap;
20
+ }
21
+
22
+ const resolveInstanceXML = async (input: ResolvableFormInstanceInput): Promise<string> => {
23
+ const instanceResult = await input.resolveInstance();
24
+
25
+ if (typeof instanceResult === 'string') {
26
+ return instanceResult;
27
+ }
28
+
29
+ if (instanceResult instanceof Blob) {
30
+ return getBlobText(instanceResult);
31
+ }
32
+
33
+ return instanceResult.text();
34
+ };
35
+
36
+ const parseInstanceDocument = (model: ModelDefinition, instanceXML: string): StaticDocument => {
37
+ const doc = parseInstanceXML(model, instanceXML);
38
+
39
+ /**
40
+ * Note: this is presently inferred as nullable. Its presence is _currently_
41
+ * enforced by {@link XFormDOM}, though that's definitely not ideal!
42
+ *
43
+ * @todo we would probably benefit from a single parse function responsible
44
+ * for both instance documents (form and input), with all `id` enforcement
45
+ * handled in one place (presence in both cases, matching in case of form +
46
+ * input). We could then also express this at the type level without weird DOM
47
+ * shenanigans in {@link XFormDOM} (which aren't likely to stick around in
48
+ * their current state forever!).
49
+ */
50
+ const expectedId = model.instance.root.getAttributeValue('id');
51
+ const actualId = doc.root.getAttributeValue('id');
52
+
53
+ if (expectedId !== actualId) {
54
+ throw new ErrorProductionDesignPendingError(
55
+ `Invalid instance input. Expected instance id to be "${expectedId}", got: "${actualId}"`
56
+ );
57
+ }
58
+
59
+ return doc;
60
+ };
61
+
62
+ export class InitialInstanceState {
63
+ static async from(
64
+ model: ModelDefinition,
65
+ data: InitialInstanceStateSources
66
+ ): Promise<InitialInstanceState> {
67
+ return this.resolve(model, {
68
+ inputType: 'FORM_INSTANCE_INPUT_RESOLVED',
69
+ data,
70
+ });
71
+ }
72
+
73
+ static async resolve(
74
+ model: ModelDefinition,
75
+ input: EditFormInstanceInput
76
+ ): Promise<InitialInstanceState> {
77
+ if (input.inputType === 'FORM_INSTANCE_INPUT_RESOLVED') {
78
+ const { data } = input;
79
+ const [instanceData] = data;
80
+ const instanceFile = instanceData.get(INSTANCE_FILE_NAME);
81
+ const instanceXML = await getBlobText(instanceFile);
82
+ const attachments = InstanceAttachmentMap.from(data);
83
+
84
+ return new this(model, {
85
+ instanceXML,
86
+ attachments,
87
+ });
88
+ }
89
+
90
+ const [instanceXML, attachments] = await Promise.all([
91
+ resolveInstanceXML(input),
92
+ InstanceAttachmentMap.resolve(input.attachments),
93
+ ]);
94
+
95
+ return new this(model, {
96
+ instanceXML,
97
+ attachments,
98
+ });
99
+ }
100
+
101
+ readonly document: StaticDocument;
102
+ readonly attachments: InstanceAttachmentMap;
103
+
104
+ private constructor(model: ModelDefinition, options: InitialInstanceStateOptions) {
105
+ this.document = parseInstanceDocument(model, options.instanceXML);
106
+ this.attachments = options.attachments;
107
+ }
108
+ }
@@ -0,0 +1,154 @@
1
+ import { getBlobData } from '@getodk/common/lib/web-compat/blob.ts';
2
+ import { INSTANCE_FILE_NAME } from '../../client/constants.ts';
3
+ import type { ResolvableInstanceAttachmentsMap } from '../../client/form/EditFormInstance.ts';
4
+ import { MalformedInstanceDataError } from '../../error/MalformedInstanceDataError.ts';
5
+ import { getResponseContentType } from '../../lib/resource-helpers.ts';
6
+ import type { FetchResourceResponse } from '../resource.ts';
7
+
8
+ type InstanceAttachmentMapSourceEntry = readonly [key: string, value: FormDataEntryValue];
9
+
10
+ interface InstanceAttachmentMapSource {
11
+ entries(): Iterable<InstanceAttachmentMapSourceEntry>;
12
+ }
13
+
14
+ type InstanceAttachmentMapSources = readonly [
15
+ InstanceAttachmentMapSource,
16
+ ...InstanceAttachmentMapSource[],
17
+ ];
18
+
19
+ const DEFAULT_ATTACHMENT_TYPE = 'application/octet-stream';
20
+
21
+ const resolveContentType = (response: FetchResourceResponse, blob: Blob): string => {
22
+ let result = blob.type;
23
+
24
+ if (result === '') {
25
+ result = getResponseContentType(response) ?? result;
26
+ }
27
+
28
+ if (result === '') {
29
+ return DEFAULT_ATTACHMENT_TYPE;
30
+ }
31
+
32
+ return result;
33
+ };
34
+
35
+ const resolveInstanceAttachmentFile = async (
36
+ response: FetchResourceResponse,
37
+ fileName: string
38
+ ): Promise<File> => {
39
+ const blob = await response.blob();
40
+ const blobData = await getBlobData(blob);
41
+
42
+ return new File([blobData], fileName, {
43
+ type: resolveContentType(response, blob),
44
+ });
45
+ };
46
+
47
+ /**
48
+ * @todo Everything about this is incredibly naive! We should almost certainly
49
+ * do _at least_ the following:
50
+ *
51
+ * - Limit how many attachments we attempt to resolve concurrently
52
+ * - Lazy resolution of large attachments (i.e. probably streaming, maybe range
53
+ * requests, ?)
54
+ *
55
+ * @todo Once lazy resolution is a thing, we will **also** need a clear path
56
+ * from there to eager resolution (i.e. for offline caching: it doesn't make
57
+ * sense to cache a stream in progress, as it won't load the resource once the
58
+ * user actually is offline/lacks network access). This may be something we can
59
+ * evolve gradually!
60
+ */
61
+ const resolveInstanceAttachmentMapSource = async (
62
+ input: ResolvableInstanceAttachmentsMap
63
+ ): Promise<InstanceAttachmentMapSource> => {
64
+ const entries = await Promise.all<InstanceAttachmentMapSourceEntry>(
65
+ Array.from(input.entries()).map(async ([fileName, resolveAttachment]) => {
66
+ const response = await resolveAttachment();
67
+ const value = await resolveInstanceAttachmentFile(response, fileName);
68
+
69
+ return [fileName, value] as const;
70
+ })
71
+ );
72
+
73
+ return { entries: () => entries };
74
+ };
75
+
76
+ interface KeyedInstanceDataFile<Key extends string> extends File {
77
+ readonly name: Key;
78
+ }
79
+
80
+ type AssertKeyedInstanceDataFile = <Key extends string>(
81
+ key: Key,
82
+ file: File
83
+ ) => asserts file is KeyedInstanceDataFile<Key>;
84
+
85
+ const assertKeyedInstanceDataFile: AssertKeyedInstanceDataFile = (key, file) => {
86
+ if (file.name !== key) {
87
+ throw new MalformedInstanceDataError(
88
+ `Unexpected InstanceData file. Expected file name to match key, got key: ${JSON.stringify(key)} and file name: ${JSON.stringify(file.name)}`
89
+ );
90
+ }
91
+ };
92
+
93
+ type UnknownInstanceDataEntry = readonly [key: string, value: FormDataEntryValue];
94
+
95
+ type KeyedInstanceDataEntry<Key extends string> = readonly [key: Key, KeyedInstanceDataFile<Key>];
96
+
97
+ type AssertInstanceDataEntry = <Key extends string>(
98
+ entry: UnknownInstanceDataEntry
99
+ ) => asserts entry is KeyedInstanceDataEntry<Key>;
100
+
101
+ const assertInstanceDataEntry: AssertInstanceDataEntry = (entry) => {
102
+ const [key, value] = entry;
103
+
104
+ if (!(value instanceof File)) {
105
+ throw new MalformedInstanceDataError(
106
+ `Unexpected non-file attachment in InstanceData for key: ${key}`
107
+ );
108
+ }
109
+
110
+ assertKeyedInstanceDataFile(key, value);
111
+ };
112
+
113
+ export class InstanceAttachmentMap extends Map<string, File> {
114
+ static from(sources: InstanceAttachmentMapSources): InstanceAttachmentMap {
115
+ return new this(sources);
116
+ }
117
+
118
+ /**
119
+ * @todo
120
+ * @see {@link resolveInstanceAttachmentMapSource}
121
+ */
122
+ static async resolve(input: ResolvableInstanceAttachmentsMap): Promise<InstanceAttachmentMap> {
123
+ const source = await resolveInstanceAttachmentMapSource(input);
124
+
125
+ return new this([source]);
126
+ }
127
+
128
+ private constructor(sources: InstanceAttachmentMapSources) {
129
+ super();
130
+
131
+ for (const source of sources) {
132
+ for (const entry of source.entries()) {
133
+ const [key] = entry;
134
+
135
+ // Skip the instance XML file: it's not an attachment!
136
+ if (key === INSTANCE_FILE_NAME) {
137
+ continue;
138
+ }
139
+
140
+ if (this.has(key)) {
141
+ throw new MalformedInstanceDataError(
142
+ `Unexpected InstanceData entry. Duplicate instance attachment for key: ${JSON.stringify(key)}`
143
+ );
144
+ }
145
+
146
+ assertInstanceDataEntry(entry);
147
+
148
+ const [, value] = entry;
149
+
150
+ this.set(key, value);
151
+ }
152
+ }
153
+ }
154
+ }
@@ -0,0 +1,20 @@
1
+ import type { Accessor } from 'solid-js';
2
+ import type { FormNodeID } from '../../client/identity.ts';
3
+ import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
4
+ import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
5
+ import type { InstanceAttachmentsState } from '../attachments/InstanceAttachmentsState.ts';
6
+ import type { InstanceConfig } from './InstanceConfig.ts';
7
+
8
+ interface InstanceAttachmentRootDocument {
9
+ readonly attachments: InstanceAttachmentsState;
10
+ }
11
+
12
+ export interface InstanceAttachmentContext {
13
+ readonly instanceConfig: InstanceConfig;
14
+ readonly scope: ReactiveScope;
15
+ readonly rootDocument: InstanceAttachmentRootDocument;
16
+ readonly nodeId: FormNodeID;
17
+ readonly instanceNode: StaticLeafElement | null;
18
+ readonly isRelevant: Accessor<boolean>;
19
+ readonly isAttached: Accessor<boolean>;
20
+ }
@@ -1,16 +1,12 @@
1
- import type { MissingResourceBehavior } from '../../client/constants.ts';
1
+ import type { InstanceAttachmentFileNameFactory } from '../../client/attachments/InstanceAttachmentsConfig.ts';
2
+ import type { FormInstanceConfig } from '../../client/form/FormInstanceConfig.ts';
2
3
  import type { OpaqueReactiveObjectFactory } from '../../client/OpaqueReactiveObjectFactory.ts';
3
- import type { FetchFormAttachment, FetchResource } from '../../client/resources.ts';
4
- import type { CreateUniqueId } from '../../lib/unique-id.ts';
5
4
 
6
5
  export interface InstanceConfig {
7
- readonly stateFactory: OpaqueReactiveObjectFactory;
8
- readonly fetchFormDefinition: FetchResource;
9
- readonly fetchFormAttachment: FetchFormAttachment;
10
- readonly missingResourceBehavior: MissingResourceBehavior;
11
-
12
6
  /**
13
- * Uniqueness per form instance session (so e.g. persistence isn't necessary).
7
+ * @see {@link FormInstanceConfig.stateFactory}
14
8
  */
15
- readonly createUniqueId: CreateUniqueId;
9
+ readonly clientStateFactory: OpaqueReactiveObjectFactory;
10
+
11
+ readonly computeAttachmentName: InstanceAttachmentFileNameFactory;
16
12
  }