@getodk/xforms-engine 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) 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/constants.d.ts +11 -12
  5. package/dist/client/form/CreateFormInstance.d.ts +14 -0
  6. package/dist/client/form/EditFormInstance.d.ts +62 -0
  7. package/dist/client/form/FormInstance.d.ts +104 -0
  8. package/dist/client/form/FormInstanceConfig.d.ts +17 -0
  9. package/dist/client/form/FormResource.d.ts +1 -0
  10. package/dist/client/form/LoadForm.d.ts +79 -0
  11. package/dist/client/form/LoadFormResult.d.ts +67 -0
  12. package/dist/client/form/RestoreFormInstance.d.ts +8 -0
  13. package/dist/client/index.d.ts +37 -11
  14. package/dist/client/node-types.d.ts +2 -2
  15. package/dist/client/repeat/BaseRepeatRangeNode.d.ts +3 -4
  16. package/dist/client/repeat/RepeatInstanceNode.d.ts +4 -5
  17. package/dist/client/repeat/RepeatRangeControlledNode.d.ts +2 -2
  18. package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +2 -2
  19. package/dist/client/resources.d.ts +1 -1
  20. package/dist/client/serialization/InstanceData.d.ts +12 -0
  21. package/dist/client/serialization/InstanceFile.d.ts +6 -0
  22. package/dist/client/serialization/InstancePayload.d.ts +93 -0
  23. package/dist/client/serialization/InstancePayloadOptions.d.ts +23 -0
  24. package/dist/client/serialization/InstanceState.d.ts +12 -0
  25. package/dist/client/submission/{SubmissionDefinition.d.ts → SubmissionMeta.d.ts} +1 -1
  26. package/dist/entrypoints/FormInstance.d.ts +20 -0
  27. package/dist/entrypoints/FormResult/BaseFormResult.d.ts +22 -0
  28. package/dist/entrypoints/FormResult/BaseInstantiableFormResult.d.ts +25 -0
  29. package/dist/entrypoints/FormResult/FormFailureResult.d.ts +17 -0
  30. package/dist/entrypoints/FormResult/FormSuccessResult.d.ts +15 -0
  31. package/dist/entrypoints/FormResult/FormWarningResult.d.ts +15 -0
  32. package/dist/entrypoints/createInstance.d.ts +9 -0
  33. package/dist/entrypoints/editInstance.d.ts +9 -0
  34. package/dist/entrypoints/index.d.ts +4 -0
  35. package/dist/entrypoints/loadForm.d.ts +4 -0
  36. package/dist/entrypoints/restoreInstance.d.ts +9 -0
  37. package/dist/error/LoadFormFailureError.d.ts +9 -0
  38. package/dist/error/MalformedInstanceDataError.d.ts +3 -0
  39. package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +22 -0
  40. package/dist/index.d.ts +2 -33
  41. package/dist/index.js +1915 -1419
  42. package/dist/index.js.map +1 -1
  43. package/dist/instance/Group.d.ts +6 -5
  44. package/dist/instance/InputControl.d.ts +5 -4
  45. package/dist/instance/ModelValue.d.ts +5 -4
  46. package/dist/instance/Note.d.ts +4 -3
  47. package/dist/instance/PrimaryInstance.d.ts +35 -8
  48. package/dist/instance/RangeControl.d.ts +5 -4
  49. package/dist/instance/RankControl.d.ts +6 -5
  50. package/dist/instance/Root.d.ts +7 -9
  51. package/dist/instance/SelectControl.d.ts +4 -3
  52. package/dist/instance/Subtree.d.ts +6 -5
  53. package/dist/instance/TriggerControl.d.ts +4 -3
  54. package/dist/instance/abstract/DescendantNode.d.ts +10 -1
  55. package/dist/instance/abstract/InstanceNode.d.ts +7 -4
  56. package/dist/instance/abstract/ValueNode.d.ts +7 -5
  57. package/dist/instance/children/DescendantNodeInitOptions.d.ts +32 -0
  58. package/dist/instance/{children.d.ts → children/buildChildren.d.ts} +1 -1
  59. package/dist/instance/children/childrenInitOptions.d.ts +9 -0
  60. package/dist/instance/children/normalizeChildInitOptions.d.ts +2 -0
  61. package/dist/instance/input/InitialInstanceState.d.ts +13 -0
  62. package/dist/instance/input/InstanceAttachmentMap.d.ts +19 -0
  63. package/dist/instance/internal-api/InstanceConfig.d.ts +2 -9
  64. package/dist/instance/internal-api/InstanceValueContext.d.ts +8 -1
  65. package/dist/instance/internal-api/serialization/ClientReactiveSerializableInstance.d.ts +14 -0
  66. package/dist/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.d.ts +32 -0
  67. package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +18 -0
  68. package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +13 -0
  69. package/dist/instance/internal-api/serialization/ClientReactiveSerializableValueNode.d.ts +21 -0
  70. package/dist/instance/repeat/BaseRepeatRange.d.ts +10 -8
  71. package/dist/instance/repeat/RepeatInstance.d.ts +10 -7
  72. package/dist/instance/repeat/RepeatRangeControlled.d.ts +27 -3
  73. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +4 -3
  74. package/dist/instance/resource.d.ts +5 -1
  75. package/dist/instance/unsupported/UploadControl.d.ts +32 -4
  76. package/dist/integration/xpath/EngineXPathEvaluator.d.ts +2 -2
  77. package/dist/integration/xpath/adapter/kind.d.ts +4 -10
  78. package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +4 -5
  79. package/dist/integration/xpath/static-dom/StaticDocument.d.ts +13 -10
  80. package/dist/integration/xpath/static-dom/StaticElement.d.ts +21 -22
  81. package/dist/integration/xpath/static-dom/StaticNode.d.ts +1 -1
  82. package/dist/integration/xpath/static-dom/StaticParentNode.d.ts +13 -0
  83. package/dist/integration/xpath/static-dom/staticNodeName.d.ts +3 -0
  84. package/dist/lib/client-reactivity/instance-state/createNodeRangeInstanceState.d.ts +4 -0
  85. package/dist/lib/client-reactivity/instance-state/createParentNodeInstanceState.d.ts +4 -0
  86. package/dist/lib/client-reactivity/instance-state/createPrimaryInstanceState.d.ts +3 -0
  87. package/dist/lib/client-reactivity/instance-state/createRootInstanceState.d.ts +3 -0
  88. package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +6 -0
  89. package/dist/lib/client-reactivity/instance-state/createValueNodeInstanceState.d.ts +3 -0
  90. package/dist/lib/client-reactivity/instance-state/prepareInstancePayload.d.ts +8 -0
  91. package/dist/lib/codecs/TempUnsupportedControlCodec.d.ts +7 -0
  92. package/dist/lib/names/UnprefixedXFormsName.d.ts +4 -0
  93. package/dist/lib/reactivity/createInstanceValueState.d.ts +2 -27
  94. package/dist/parse/XFormDOM.d.ts +1 -1
  95. package/dist/parse/model/BindDefinition.d.ts +1 -1
  96. package/dist/parse/model/ItextTranslationsDefinition.d.ts +18 -0
  97. package/dist/parse/model/LeafNodeDefinition.d.ts +4 -5
  98. package/dist/parse/model/ModelBindMap.d.ts +1 -1
  99. package/dist/parse/model/ModelDefinition.d.ts +9 -2
  100. package/dist/parse/model/NodeDefinition.d.ts +18 -30
  101. package/dist/parse/model/NoteNodeDefinition.d.ts +3 -2
  102. package/dist/parse/model/RangeNodeDefinition.d.ts +2 -1
  103. package/dist/parse/model/RepeatDefinition.d.ts +62 -0
  104. package/dist/parse/model/RootAttributeDefinition.d.ts +1 -4
  105. package/dist/parse/model/RootAttributeMap.d.ts +2 -1
  106. package/dist/parse/model/RootDefinition.d.ts +7 -8
  107. package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +15 -2
  108. package/dist/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.d.ts +5 -0
  109. package/dist/parse/model/SecondaryInstance/defineSecondaryInstance.d.ts +5 -0
  110. package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +1 -7
  111. package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +1 -1
  112. package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +1 -1
  113. package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +1 -1
  114. package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +1 -1
  115. package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +1 -1
  116. package/dist/parse/model/{FormSubmissionDefinition.d.ts → SubmissionDefinition.d.ts} +2 -2
  117. package/dist/parse/model/SubtreeDefinition.d.ts +4 -5
  118. package/dist/parse/model/nodeDefinitionMap.d.ts +5 -0
  119. package/dist/parse/shared/parseInstanceXML.d.ts +21 -0
  120. package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +4 -21
  121. package/dist/solid.js +1709 -1213
  122. package/dist/solid.js.map +1 -1
  123. package/package.json +1 -1
  124. package/src/client/BaseNode.ts +4 -4
  125. package/src/client/BaseValueNode.ts +7 -3
  126. package/src/client/RootNode.ts +27 -19
  127. package/src/client/constants.ts +12 -14
  128. package/src/client/form/CreateFormInstance.ts +19 -0
  129. package/src/client/form/EditFormInstance.ts +93 -0
  130. package/src/client/form/FormInstance.ts +114 -0
  131. package/src/client/form/FormInstanceConfig.ts +18 -0
  132. package/src/client/form/FormResource.ts +1 -0
  133. package/src/client/form/LoadForm.ts +92 -0
  134. package/src/client/form/LoadFormResult.ts +103 -0
  135. package/src/client/form/RestoreFormInstance.ts +14 -0
  136. package/src/client/index.ts +47 -29
  137. package/src/client/node-types.ts +2 -4
  138. package/src/client/repeat/BaseRepeatRangeNode.ts +3 -4
  139. package/src/client/repeat/RepeatInstanceNode.ts +4 -8
  140. package/src/client/repeat/RepeatRangeControlledNode.ts +2 -2
  141. package/src/client/repeat/RepeatRangeUncontrolledNode.ts +2 -2
  142. package/src/client/resources.ts +2 -2
  143. package/src/client/serialization/InstanceData.ts +16 -0
  144. package/src/client/serialization/InstanceFile.ts +9 -0
  145. package/src/client/serialization/InstancePayload.ts +126 -0
  146. package/src/client/serialization/InstancePayloadOptions.ts +28 -0
  147. package/src/client/serialization/InstanceState.ts +14 -0
  148. package/src/client/submission/{SubmissionDefinition.ts → SubmissionMeta.ts} +1 -1
  149. package/src/entrypoints/FormInstance.ts +55 -0
  150. package/src/entrypoints/FormResult/BaseFormResult.ts +40 -0
  151. package/src/entrypoints/FormResult/BaseInstantiableFormResult.ts +109 -0
  152. package/src/entrypoints/FormResult/FormFailureResult.ts +44 -0
  153. package/src/entrypoints/FormResult/FormSuccessResult.ts +25 -0
  154. package/src/entrypoints/FormResult/FormWarningResult.ts +25 -0
  155. package/src/entrypoints/createInstance.ts +23 -0
  156. package/src/entrypoints/editInstance.ts +24 -0
  157. package/src/entrypoints/index.ts +4 -0
  158. package/src/entrypoints/loadForm.ts +154 -0
  159. package/src/entrypoints/restoreInstance.ts +27 -0
  160. package/src/error/LoadFormFailureError.ts +114 -0
  161. package/src/error/MalformedInstanceDataError.ts +3 -0
  162. package/src/error/TemplatedNodeAttributeSerializationError.ts +24 -0
  163. package/src/index.ts +2 -46
  164. package/src/instance/Group.ts +16 -15
  165. package/src/instance/InputControl.ts +17 -11
  166. package/src/instance/ModelValue.ts +17 -11
  167. package/src/instance/Note.ts +10 -9
  168. package/src/instance/PrimaryInstance.ts +69 -31
  169. package/src/instance/RangeControl.ts +17 -11
  170. package/src/instance/RankControl.ts +28 -19
  171. package/src/instance/Root.ts +20 -31
  172. package/src/instance/SelectControl.ts +21 -12
  173. package/src/instance/Subtree.ts +16 -15
  174. package/src/instance/TriggerControl.ts +21 -12
  175. package/src/instance/abstract/DescendantNode.ts +12 -2
  176. package/src/instance/abstract/InstanceNode.ts +9 -5
  177. package/src/instance/abstract/ValueNode.ts +11 -13
  178. package/src/instance/children/DescendantNodeInitOptions.ts +35 -0
  179. package/src/instance/{children.ts → children/buildChildren.ts} +55 -48
  180. package/src/instance/children/childrenInitOptions.ts +117 -0
  181. package/src/instance/children/normalizeChildInitOptions.ts +332 -0
  182. package/src/instance/input/InitialInstanceState.ts +108 -0
  183. package/src/instance/input/InstanceAttachmentMap.ts +142 -0
  184. package/src/instance/internal-api/InstanceConfig.ts +3 -10
  185. package/src/instance/internal-api/InstanceValueContext.ts +9 -1
  186. package/src/instance/internal-api/serialization/ClientReactiveSerializableInstance.ts +20 -0
  187. package/src/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.ts +43 -0
  188. package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +26 -0
  189. package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +24 -0
  190. package/src/instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts +28 -0
  191. package/src/instance/repeat/BaseRepeatRange.ts +19 -24
  192. package/src/instance/repeat/RepeatInstance.ts +26 -19
  193. package/src/instance/repeat/RepeatRangeControlled.ts +90 -17
  194. package/src/instance/repeat/RepeatRangeUncontrolled.ts +10 -9
  195. package/src/instance/resource.ts +14 -1
  196. package/src/instance/unsupported/UploadControl.ts +116 -5
  197. package/src/integration/xpath/EngineXPathEvaluator.ts +2 -2
  198. package/src/integration/xpath/adapter/kind.ts +1 -28
  199. package/src/integration/xpath/adapter/traversal.ts +2 -2
  200. package/src/integration/xpath/static-dom/StaticAttribute.ts +6 -5
  201. package/src/integration/xpath/static-dom/StaticDocument.ts +17 -16
  202. package/src/integration/xpath/static-dom/StaticElement.ts +196 -50
  203. package/src/integration/xpath/static-dom/StaticNode.ts +1 -1
  204. package/src/integration/xpath/static-dom/StaticParentNode.ts +22 -0
  205. package/src/integration/xpath/static-dom/staticNodeName.ts +20 -0
  206. package/src/lib/client-reactivity/instance-state/createNodeRangeInstanceState.ts +17 -0
  207. package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +22 -0
  208. package/src/lib/client-reactivity/instance-state/createPrimaryInstanceState.ts +12 -0
  209. package/src/lib/client-reactivity/{submission/createRootSubmissionState.ts → instance-state/createRootInstanceState.ts} +4 -4
  210. package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +31 -0
  211. package/src/lib/client-reactivity/instance-state/createValueNodeInstanceState.ts +21 -0
  212. package/src/lib/client-reactivity/instance-state/prepareInstancePayload.ts +173 -0
  213. package/src/lib/codecs/TempUnsupportedControlCodec.ts +32 -0
  214. package/src/lib/names/UnprefixedXFormsName.ts +12 -0
  215. package/src/lib/reactivity/createInstanceValueState.ts +27 -51
  216. package/src/parse/model/ItextTranslationsDefinition.ts +79 -0
  217. package/src/parse/model/LeafNodeDefinition.ts +3 -5
  218. package/src/parse/model/ModelDefinition.ts +36 -3
  219. package/src/parse/model/NodeDefinition.ts +19 -45
  220. package/src/parse/model/NoteNodeDefinition.ts +4 -3
  221. package/src/parse/model/RangeNodeDefinition.ts +3 -2
  222. package/src/parse/model/RepeatDefinition.ts +382 -0
  223. package/src/parse/model/RootAttributeDefinition.ts +6 -7
  224. package/src/parse/model/RootAttributeMap.ts +15 -10
  225. package/src/parse/model/RootDefinition.ts +17 -19
  226. package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +23 -2
  227. package/src/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.ts +14 -0
  228. package/src/parse/model/SecondaryInstance/defineSecondaryInstance.ts +32 -0
  229. package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +3 -24
  230. package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +33 -86
  231. package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +64 -137
  232. package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +9 -7
  233. package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +1 -1
  234. package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +7 -7
  235. package/src/parse/model/{FormSubmissionDefinition.ts → SubmissionDefinition.ts} +2 -2
  236. package/src/parse/model/SubtreeDefinition.ts +4 -5
  237. package/src/parse/model/nodeDefinitionMap.ts +34 -0
  238. package/src/parse/shared/parseInstanceXML.ts +79 -0
  239. package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +45 -130
  240. package/dist/client/EngineConfig.d.ts +0 -79
  241. package/dist/client/submission/SubmissionData.d.ts +0 -7
  242. package/dist/client/submission/SubmissionInstanceFile.d.ts +0 -6
  243. package/dist/client/submission/SubmissionOptions.d.ts +0 -23
  244. package/dist/client/submission/SubmissionResult.d.ts +0 -91
  245. package/dist/client/submission/SubmissionState.d.ts +0 -12
  246. package/dist/instance/abstract/UnsupportedControl.d.ts +0 -54
  247. package/dist/instance/index.d.ts +0 -8
  248. package/dist/instance/internal-api/ValueContext.d.ts +0 -23
  249. package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +0 -14
  250. package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +0 -32
  251. package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +0 -19
  252. package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +0 -18
  253. package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +0 -3
  254. package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +0 -3
  255. package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +0 -4
  256. package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +0 -4
  257. package/dist/lib/client-reactivity/submission/createRootSubmissionState.d.ts +0 -3
  258. package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +0 -3
  259. package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +0 -8
  260. package/dist/lib/reactivity/createValueState.d.ts +0 -40
  261. package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +0 -4
  262. package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +0 -9
  263. package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +0 -8
  264. package/dist/parse/model/RepeatInstanceDefinition.d.ts +0 -17
  265. package/dist/parse/model/RepeatRangeDefinition.d.ts +0 -32
  266. package/dist/parse/model/RepeatTemplateDefinition.d.ts +0 -31
  267. package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +0 -4
  268. package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +0 -7
  269. package/src/client/EngineConfig.ts +0 -84
  270. package/src/client/submission/SubmissionData.ts +0 -12
  271. package/src/client/submission/SubmissionInstanceFile.ts +0 -9
  272. package/src/client/submission/SubmissionOptions.ts +0 -28
  273. package/src/client/submission/SubmissionResult.ts +0 -124
  274. package/src/client/submission/SubmissionState.ts +0 -14
  275. package/src/instance/abstract/UnsupportedControl.ts +0 -175
  276. package/src/instance/index.ts +0 -55
  277. package/src/instance/internal-api/ValueContext.ts +0 -28
  278. package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +0 -20
  279. package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +0 -43
  280. package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +0 -26
  281. package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +0 -24
  282. package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +0 -12
  283. package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +0 -20
  284. package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +0 -17
  285. package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +0 -22
  286. package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +0 -21
  287. package/src/lib/client-reactivity/submission/prepareSubmission.ts +0 -172
  288. package/src/lib/reactivity/createValueState.ts +0 -200
  289. package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +0 -4
  290. package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +0 -42
  291. package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +0 -31
  292. package/src/parse/model/RepeatInstanceDefinition.ts +0 -38
  293. package/src/parse/model/RepeatRangeDefinition.ts +0 -98
  294. package/src/parse/model/RepeatTemplateDefinition.ts +0 -149
  295. package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +0 -4
  296. package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +0 -12
@@ -58,7 +58,7 @@ export type AnyStaticNode =
58
58
  | StaticText;
59
59
 
60
60
  // prettier-ignore
61
- export type StaticParentNode =
61
+ export type StaticNodeParent =
62
62
  | StaticDocument
63
63
  | StaticElement;
64
64
 
@@ -0,0 +1,22 @@
1
+ import { XPathNodeKindKey } from '@getodk/xpath';
2
+ import type { StaticElement } from './StaticElement.ts';
3
+ import { StaticNode, type StaticChildNode } from './StaticNode.ts';
4
+
5
+ type StaticParentNodeKind = 'document' | 'element';
6
+
7
+ type StaticParentNodeType<Kind extends StaticParentNodeKind> = `static-${Kind}`;
8
+
9
+ export abstract class StaticParentNode<Kind extends StaticParentNodeKind> extends StaticNode<Kind> {
10
+ abstract override readonly children: readonly StaticChildNode[];
11
+ abstract readonly childElements: readonly StaticElement[];
12
+
13
+ readonly [XPathNodeKindKey]: Kind;
14
+ readonly nodeType: StaticParentNodeType<Kind>;
15
+
16
+ constructor(kind: Kind) {
17
+ super();
18
+
19
+ this[XPathNodeKindKey] = kind;
20
+ this.nodeType = `static-${kind}`;
21
+ }
22
+ }
@@ -0,0 +1,20 @@
1
+ import { QualifiedName, type QualifiedNameSource } from '../../../lib/names/QualifiedName.ts';
2
+ import { UnprefixedXFormsName } from '../../../lib/names/UnprefixedXFormsName.ts';
3
+
4
+ // prettier-ignore
5
+ export type StaticNodeNameSource =
6
+ | QualifiedName
7
+ | QualifiedNameSource
8
+ | string;
9
+
10
+ export const staticNodeName = (source: StaticNodeNameSource): QualifiedName => {
11
+ if (source instanceof QualifiedName) {
12
+ return source;
13
+ }
14
+
15
+ if (typeof source === 'string') {
16
+ return new UnprefixedXFormsName(source);
17
+ }
18
+
19
+ return new QualifiedName(source);
20
+ };
@@ -0,0 +1,17 @@
1
+ import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
+ import type { ClientReactiveSerializableParentNode } from '../../../instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts';
3
+ import type { RepeatInstance } from '../../../instance/repeat/RepeatInstance.ts';
4
+
5
+ export const createNodeRangeInstanceState = (
6
+ node: ClientReactiveSerializableParentNode<RepeatInstance>
7
+ ): InstanceState => {
8
+ return {
9
+ get instanceXML() {
10
+ const serializedChildren = node.currentState.children.map((child) => {
11
+ return child.instanceState.instanceXML;
12
+ });
13
+
14
+ return serializedChildren.join('');
15
+ },
16
+ };
17
+ };
@@ -0,0 +1,22 @@
1
+ import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
+ import type { GeneralChildNode } from '../../../instance/hierarchy.ts';
3
+ import type { ClientReactiveSerializableParentNode } from '../../../instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts';
4
+ import { serializeParentElementXML } from '../../xml-serialization.ts';
5
+
6
+ export const createParentNodeInstanceState = (
7
+ node: ClientReactiveSerializableParentNode<GeneralChildNode>
8
+ ): InstanceState => {
9
+ return {
10
+ get instanceXML() {
11
+ if (!node.currentState.relevant) {
12
+ return '';
13
+ }
14
+
15
+ const serializedChildren = node.currentState.children.map((child) => {
16
+ return child.instanceState.instanceXML;
17
+ });
18
+
19
+ return serializeParentElementXML(node.definition.qualifiedName, serializedChildren);
20
+ },
21
+ };
22
+ };
@@ -0,0 +1,12 @@
1
+ import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
+ import type { ClientReactiveSerializableInstance } from '../../../instance/internal-api/serialization/ClientReactiveSerializableInstance.ts';
3
+
4
+ export const createPrimaryInstanceState = (
5
+ node: ClientReactiveSerializableInstance
6
+ ): InstanceState => {
7
+ return {
8
+ get instanceXML(): string {
9
+ return node.root.instanceState.instanceXML;
10
+ },
11
+ };
12
+ };
@@ -1,13 +1,13 @@
1
- import type { SubmissionState } from '../../../client/submission/SubmissionState.ts';
1
+ import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
2
  import type { Root } from '../../../instance/Root.ts';
3
3
  import { serializeParentElementXML } from '../../xml-serialization.ts';
4
4
 
5
- export const createRootSubmissionState = (node: Root): SubmissionState => {
5
+ export const createRootInstanceState = (node: Root): InstanceState => {
6
6
  return {
7
- get submissionXML() {
7
+ get instanceXML() {
8
8
  const { namespaceDeclarations, attributes } = node.definition;
9
9
  const serializedChildren = node.currentState.children.map((child) => {
10
- return child.submissionState.submissionXML;
10
+ return child.instanceState.instanceXML;
11
11
  });
12
12
 
13
13
  return serializeParentElementXML(node.definition.qualifiedName, serializedChildren, {
@@ -0,0 +1,31 @@
1
+ import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
+ import { TemplatedNodeAttributeSerializationError } from '../../../error/TemplatedNodeAttributeSerializationError.ts';
3
+ import type { ClientReactiveSerializableTemplatedNode } from '../../../instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts';
4
+ import { serializeParentElementXML } from '../../xml-serialization.ts';
5
+
6
+ /**
7
+ * @see {@link TemplatedNodeAttributeSerializationError}
8
+ */
9
+ export const createTemplatedNodeInstanceState = (
10
+ node: ClientReactiveSerializableTemplatedNode
11
+ ): InstanceState => {
12
+ return {
13
+ get instanceXML() {
14
+ if (!node.currentState.relevant) {
15
+ return '';
16
+ }
17
+
18
+ const serializedChildren = node.currentState.children.map((child) => {
19
+ return child.instanceState.instanceXML;
20
+ });
21
+
22
+ const { attributes } = node.currentState;
23
+
24
+ if (attributes != null) {
25
+ throw new TemplatedNodeAttributeSerializationError();
26
+ }
27
+
28
+ return serializeParentElementXML(node.definition.qualifiedName, serializedChildren);
29
+ },
30
+ };
31
+ };
@@ -0,0 +1,21 @@
1
+ import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
+ import type { ClientReactiveSerializableValueNode } from '../../../instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts';
3
+ import { escapeXMLText, serializeLeafElementXML } from '../../xml-serialization.ts';
4
+
5
+ export const createValueNodeInstanceState = (
6
+ node: ClientReactiveSerializableValueNode
7
+ ): InstanceState => {
8
+ const { qualifiedName } = node.definition;
9
+
10
+ return {
11
+ get instanceXML() {
12
+ if (!node.currentState.relevant) {
13
+ return '';
14
+ }
15
+
16
+ const xmlValue = escapeXMLText(node.currentState.instanceValue);
17
+
18
+ return serializeLeafElementXML(qualifiedName, xmlValue);
19
+ },
20
+ };
21
+ };
@@ -0,0 +1,173 @@
1
+ import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
2
+ import { INSTANCE_FILE_NAME, INSTANCE_FILE_TYPE } from '../../../client/constants.ts';
3
+ import type { InstanceData as ClientInstanceData } from '../../../client/serialization/InstanceData.ts';
4
+ import type { InstanceFile as ClientInstanceFile } from '../../../client/serialization/InstanceFile.ts';
5
+ import type {
6
+ ChunkedInstancePayload,
7
+ InstancePayload,
8
+ MonolithicInstancePayload,
9
+ } from '../../../client/serialization/InstancePayload.ts';
10
+ import type { InstancePayloadType } from '../../../client/serialization/InstancePayloadOptions.ts';
11
+ import type { SubmissionMeta } from '../../../client/submission/SubmissionMeta.ts';
12
+ import type { DescendantNodeViolationReference } from '../../../client/validation.ts';
13
+ import type { ClientReactiveSerializableInstance } from '../../../instance/internal-api/serialization/ClientReactiveSerializableInstance.ts';
14
+
15
+ class InstanceFile extends File implements ClientInstanceFile {
16
+ override readonly name = INSTANCE_FILE_NAME;
17
+ override readonly type = INSTANCE_FILE_TYPE;
18
+
19
+ constructor(instanceRoot: ClientReactiveSerializableInstance) {
20
+ const { instanceXML } = instanceRoot.instanceState;
21
+
22
+ super([instanceXML], INSTANCE_FILE_NAME, {
23
+ type: INSTANCE_FILE_TYPE,
24
+ });
25
+ }
26
+ }
27
+
28
+ type AssertInstanceData = (data: FormData) => asserts data is ClientInstanceData;
29
+
30
+ const assertInstanceData: AssertInstanceData = (data) => {
31
+ const instanceFile = data.get(INSTANCE_FILE_NAME);
32
+
33
+ if (!(instanceFile instanceof InstanceFile)) {
34
+ throw new Error(`Invalid InstanceData`);
35
+ }
36
+ };
37
+
38
+ class InstanceData extends FormData {
39
+ static from(instanceFile: InstanceFile, attachments: readonly File[]): ClientInstanceData {
40
+ const data = new this(instanceFile, attachments);
41
+
42
+ assertInstanceData(data);
43
+
44
+ return data;
45
+ }
46
+
47
+ private constructor(
48
+ readonly instanceFile: InstanceFile,
49
+ readonly attachments: readonly File[]
50
+ ) {
51
+ super();
52
+
53
+ this.set(INSTANCE_FILE_NAME, instanceFile);
54
+
55
+ attachments.forEach((attachment) => {
56
+ const { name } = attachment;
57
+
58
+ if (name === INSTANCE_FILE_NAME && attachment !== instanceFile) {
59
+ throw new Error(`Failed to add conflicting attachment with name ${INSTANCE_FILE_NAME}`);
60
+ }
61
+
62
+ this.set(name, attachment);
63
+ });
64
+ }
65
+ }
66
+
67
+ interface PendingValidation {
68
+ readonly status: 'pending';
69
+ readonly violations: readonly DescendantNodeViolationReference[];
70
+ }
71
+
72
+ interface ReadyValidation {
73
+ readonly status: 'ready';
74
+ readonly violations: null;
75
+ }
76
+
77
+ type InstanceStateValidation = PendingValidation | ReadyValidation;
78
+
79
+ const validateInstance = (
80
+ instanceRoot: ClientReactiveSerializableInstance
81
+ ): InstanceStateValidation => {
82
+ const { violations } = instanceRoot.validationState;
83
+
84
+ if (violations.length === 0) {
85
+ return {
86
+ status: 'ready',
87
+ violations: null,
88
+ };
89
+ }
90
+
91
+ return {
92
+ status: 'pending',
93
+ violations,
94
+ };
95
+ };
96
+
97
+ const monolithicInstancePayload = (
98
+ validation: InstanceStateValidation,
99
+ submissionMeta: SubmissionMeta,
100
+ instanceFile: InstanceFile,
101
+ attachments: readonly File[]
102
+ ): MonolithicInstancePayload => {
103
+ const data = InstanceData.from(instanceFile, attachments);
104
+
105
+ return {
106
+ payloadType: 'monolithic',
107
+ ...validation,
108
+ submissionMeta,
109
+ data: [data],
110
+ };
111
+ };
112
+
113
+ interface ChunkedInstancePayloadOptions {
114
+ readonly maxSize: number;
115
+ }
116
+
117
+ const chunkedInstancePayload = (
118
+ validation: InstanceStateValidation,
119
+ submissionMeta: SubmissionMeta,
120
+ instanceFile: InstanceFile,
121
+ attachments: readonly File[],
122
+ options: ChunkedInstancePayloadOptions
123
+ ): ChunkedInstancePayload => {
124
+ if (attachments.length > 0 || options.maxSize !== Infinity) {
125
+ throw new Error('InstancePayload chunking pending implementation');
126
+ }
127
+
128
+ const data = InstanceData.from(instanceFile, attachments);
129
+
130
+ return {
131
+ payloadType: 'chunked',
132
+ ...validation,
133
+ submissionMeta,
134
+ data: [data],
135
+ };
136
+ };
137
+
138
+ export interface PrepareInstancePayloadOptions<PayloadType extends InstancePayloadType> {
139
+ readonly payloadType: PayloadType;
140
+ readonly maxSize: number;
141
+ }
142
+
143
+ export const prepareInstancePayload = <PayloadType extends InstancePayloadType>(
144
+ instanceRoot: ClientReactiveSerializableInstance,
145
+ options: PrepareInstancePayloadOptions<PayloadType>
146
+ ): InstancePayload<PayloadType> => {
147
+ const validation = validateInstance(instanceRoot);
148
+ const submissionMeta = instanceRoot.definition.submission;
149
+ const instanceFile = new InstanceFile(instanceRoot);
150
+ const attachments: readonly File[] = [];
151
+
152
+ switch (options.payloadType) {
153
+ case 'chunked':
154
+ return chunkedInstancePayload(
155
+ validation,
156
+ submissionMeta,
157
+ instanceFile,
158
+ attachments,
159
+ options
160
+ ) satisfies ChunkedInstancePayload as InstancePayload<PayloadType>;
161
+
162
+ case 'monolithic':
163
+ return monolithicInstancePayload(
164
+ validation,
165
+ submissionMeta,
166
+ instanceFile,
167
+ attachments
168
+ ) satisfies MonolithicInstancePayload as InstancePayload<PayloadType>;
169
+
170
+ default:
171
+ throw new UnreachableError(options.payloadType);
172
+ }
173
+ };
@@ -0,0 +1,32 @@
1
+ import { identity } from '@getodk/common/lib/identity.ts';
2
+ import type { ValueType } from '../../client/ValueType.ts';
3
+ import { ValueCodec, type CodecDecoder, type CodecEncoder } from './ValueCodec.ts';
4
+
5
+ class TempUnsupportedControlEncodeError extends Error {
6
+ constructor() {
7
+ super(`Cannot encode state: not implemented`);
8
+ }
9
+ }
10
+
11
+ export type TempUnsupportedRuntimeValue = unknown;
12
+ export type TempUnsupportedInputValue = unknown;
13
+
14
+ export class TempUnsupportedControlCodec<V extends ValueType> extends ValueCodec<
15
+ V,
16
+ TempUnsupportedRuntimeValue,
17
+ TempUnsupportedInputValue
18
+ > {
19
+ constructor(valueType: V) {
20
+ const encodeValue: CodecEncoder<TempUnsupportedRuntimeValue> = (input): string => {
21
+ if (typeof input === 'string') {
22
+ return input;
23
+ }
24
+
25
+ throw new TempUnsupportedControlEncodeError();
26
+ };
27
+
28
+ const decodeValue: CodecDecoder<TempUnsupportedInputValue> = identity;
29
+
30
+ super(valueType, encodeValue, decodeValue);
31
+ }
32
+ }
@@ -0,0 +1,12 @@
1
+ import { XFORMS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
2
+ import { QualifiedName } from './QualifiedName.ts';
3
+
4
+ export class UnprefixedXFormsName extends QualifiedName {
5
+ constructor(localName: string) {
6
+ super({
7
+ namespaceURI: XFORMS_NAMESPACE_URI,
8
+ prefix: null,
9
+ localName,
10
+ });
11
+ }
12
+ }
@@ -1,57 +1,27 @@
1
1
  import type { Signal } from 'solid-js';
2
2
  import { createComputed, createMemo, createSignal, untrack } from 'solid-js';
3
- import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
4
3
  import type { InstanceValueContext } from '../../instance/internal-api/InstanceValueContext.ts';
5
4
  import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
6
5
  import { createComputedExpression } from './createComputedExpression.ts';
7
6
  import type { SimpleAtomicState, SimpleAtomicStateSetter } from './types.ts';
8
7
 
9
- type InitialValueSource = 'FORM_DEFAULT' | 'PRIMARY_INSTANCE';
8
+ const isInstanceFirstLoad = (context: InstanceValueContext) => {
9
+ return context.rootDocument.initializationMode === 'create';
10
+ };
10
11
 
11
12
  /**
12
- * @todo {@link InitialValueSource} naming leaves a lot to be desired. As described in {@link InstanceValueStateOptions.initialValueSource}, this check (for now) will effectively answer the question: "are we **NOT** editing instance state (e.g. a submission)?". This answer, in turn, determines whether to {@link setPreloadUIDValue}
13
+ * Special case, does not correspond to any event.
14
+ *
15
+ * @see {@link shouldPreloadUID}
13
16
  */
14
- const isInstanceFirstLoad = (valueSource?: InitialValueSource) => {
15
- return valueSource === 'FORM_DEFAULT';
17
+ const isEditInitialLoad = (context: InstanceValueContext) => {
18
+ return context.rootDocument.initializationMode === 'edit';
16
19
  };
17
20
 
18
- export interface InstanceValueStateOptions {
19
- /**
20
- * Specifies the source of a {@link createInstanceValueState} signal's initial
21
- * value state, where:
22
- *
23
- * - 'FORM_DEFAULT': Derives the initial state from the form's definition of
24
- * the node itself. This is the default option, appropriate when
25
- * initializing a form without additional primary instance data. In other
26
- * words, this value should not be used for edits.
27
- *
28
- * - 'PRIMARY_INSTANCE': Derives the initial state from the current text
29
- * content of the {@link ValueNode.contextNode}. This option should be
30
- * specified when initializing a form with existing primary instance data,
31
- * such as when editing a previous submission.
32
- *
33
- * @default 'FORM_DEFAULT'
34
- *
35
- * Specifies whether a {@link createInstanceValueState} signal's initial state
36
- * should be derived from the current text content of the
37
- * {@link ValueNode.contextNode | primary instance DOM state}.
38
- */
39
- readonly initialValueSource?: InitialValueSource;
40
- }
41
-
42
- const getInitialValue = (
43
- context: InstanceValueContext,
44
- options: InstanceValueStateOptions
45
- ): string => {
46
- const { initialValueSource = 'FORM_DEFAULT' } = options;
47
-
48
- if (initialValueSource === 'FORM_DEFAULT') {
49
- const { defaultValue } = context.definition;
50
-
51
- return context.decodeInstanceValue(defaultValue);
52
- }
21
+ const getInitialValue = (context: InstanceValueContext): string => {
22
+ const sourceNode = context.instanceNode ?? context.definition.template;
53
23
 
54
- throw new ErrorProductionDesignPendingError('Edit implementation pending');
24
+ return context.decodeInstanceValue(sourceNode.value);
55
25
  };
56
26
 
57
27
  type BaseValueState = Signal<string>;
@@ -118,6 +88,16 @@ const guardDownstreamReadonlyWrites = (
118
88
  */
119
89
  const PRELOAD_UID_EXPRESSION = 'concat("uuid:", uuid())';
120
90
 
91
+ /**
92
+ * @todo It feels increasingly awkward to keep piling up preload stuff here, but it won't stay that way for long. In the meantime, this seems like the best way to express the cases where `preload="uid"` should be effective, i.e.:
93
+ *
94
+ * - When an instance is first loaded ({@link isInstanceFirstLoad})
95
+ * - When an instance is initially loaded for editing ({@link isEditInitialLoad})
96
+ */
97
+ const shouldPreloadUID = (context: InstanceValueContext) => {
98
+ return isInstanceFirstLoad(context) || isEditInitialLoad(context);
99
+ };
100
+
121
101
  /**
122
102
  * @todo This is a temporary one-off, until we support the full range of
123
103
  * {@link https://getodk.github.io/xforms-spec/#preload-attributes | preloads}.
@@ -129,12 +109,11 @@ const PRELOAD_UID_EXPRESSION = 'concat("uuid:", uuid())';
129
109
  */
130
110
  const setPreloadUIDValue = (
131
111
  context: InstanceValueContext,
132
- valueState: RelevantValueState,
133
- options: InstanceValueStateOptions
112
+ valueState: RelevantValueState
134
113
  ): void => {
135
114
  const { preload } = context.definition.bind;
136
115
 
137
- if (preload?.type !== 'uid' || !isInstanceFirstLoad(options?.initialValueSource)) {
116
+ if (preload?.type !== 'uid' || !shouldPreloadUID(context)) {
138
117
  return;
139
118
  }
140
119
 
@@ -182,26 +161,23 @@ export type InstanceValueState = SimpleAtomicState<string>;
182
161
  * Provides a consistent interface for value nodes of any type which:
183
162
  *
184
163
  * - derives initial state from either an existing instance (e.g. for edits) or
185
- * the node's definition (e.g. initializing a new submission)
164
+ * the node's definition (e.g. initializing a new instance)
186
165
  * - decodes current primary instance state into the value node's runtime type
187
166
  * - encodes updated runtime values to store updated instance state
188
167
  * - initializes reactive computation of `calculate` bind expressions for those
189
168
  * nodes defined with one
190
169
  * - prevents downstream writes to nodes in a readonly state
191
170
  */
192
- export const createInstanceValueState = (
193
- context: InstanceValueContext,
194
- options: InstanceValueStateOptions = {}
195
- ): InstanceValueState => {
171
+ export const createInstanceValueState = (context: InstanceValueContext): InstanceValueState => {
196
172
  return context.scope.runTask(() => {
197
- const initialValue = getInitialValue(context, options);
173
+ const initialValue = getInitialValue(context);
198
174
  const baseValueState = createSignal(initialValue);
199
175
  const relevantValueState = createRelevantValueState(context, baseValueState);
200
176
 
201
177
  /**
202
178
  * @see {@link setPreloadUIDValue} for important details about spec ordering of events and computations.
203
179
  */
204
- setPreloadUIDValue(context, relevantValueState, options);
180
+ setPreloadUIDValue(context, relevantValueState);
205
181
 
206
182
  const { calculate } = context.definition.bind;
207
183
 
@@ -0,0 +1,79 @@
1
+ import type {
2
+ XFORMS_KNOWN_ATTRIBUTE,
3
+ XFORMS_LOCAL_NAME,
4
+ XFormsItextTranslationMap,
5
+ } from '@getodk/xpath';
6
+ import { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
7
+ import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
8
+ import type { XFormDOM } from '../XFormDOM.ts';
9
+ import { parseStaticDocumentFromDOMSubtree } from '../shared/parseStaticDocumentFromDOMSubtree.ts';
10
+
11
+ export interface ItextTranslationDefinition extends StaticDocument {
12
+ readonly rootDocument: ItextTranslationDefinition;
13
+ readonly root: ItextTranslationRootDefinition;
14
+ }
15
+
16
+ export interface ItextTranslationRootDefinition extends StaticElement {
17
+ readonly [XFORMS_LOCAL_NAME]: 'translation';
18
+ readonly [XFORMS_KNOWN_ATTRIBUTE]: 'lang';
19
+
20
+ readonly root: ItextTranslationRootDefinition;
21
+ readonly rootDocument: ItextTranslationDefinition;
22
+ }
23
+
24
+ type ItextTranslationsDefinitionEntry = readonly [
25
+ key: string,
26
+ value: ItextTranslationRootDefinition,
27
+ ];
28
+
29
+ type AssertItextTranslationsDefinitionEntry = (
30
+ entry: readonly [key: string | null, value: StaticElement]
31
+ ) => asserts entry is ItextTranslationsDefinitionEntry;
32
+
33
+ const assertItextTranslationsDefinitionEntry: AssertItextTranslationsDefinitionEntry = ([
34
+ key,
35
+ root,
36
+ ]) => {
37
+ if (key == null || root.qualifiedName.localName !== 'translation') {
38
+ throw new Error();
39
+ }
40
+ };
41
+
42
+ /**
43
+ * @todo At time of writing, this shouldn't have any observable
44
+ * consequence—apart from preventing the potential mistake of using an
45
+ * {@link ItextTranslationDefinition} where an
46
+ * **instance**-as-{@link StaticDocument} would be expected (i.e. anything
47
+ * expecting an instance's {@link StaticDocument.nodeset} to be '/', or an its
48
+ * descendant elements' {@link StaticElement.nodeset} to start with '/'). The
49
+ * main intent, however, is to leave a breadcrumb back to ideas discussed in
50
+ * {@link https://github.com/getodk/web-forms/issues/22#issuecomment-2669228571 | Allow output in translation text (#22)}.
51
+ */
52
+ const itextTranslationNodesetPrefix = (lang: string) => {
53
+ return `wf:translation('${lang}')`;
54
+ };
55
+
56
+ export class ItextTranslationsDefinition
57
+ extends Map<string, ItextTranslationRootDefinition>
58
+ implements XFormsItextTranslationMap<ItextTranslationRootDefinition>
59
+ {
60
+ static from(xformDOM: XFormDOM): ItextTranslationsDefinition {
61
+ const entries = xformDOM.itextTranslationElements.map((element) => {
62
+ const lang = element.getAttribute('lang');
63
+ const { root } = parseStaticDocumentFromDOMSubtree(element, {
64
+ nodesetPrefix: itextTranslationNodesetPrefix(lang),
65
+ });
66
+ const entry = [lang, root] as const;
67
+
68
+ assertItextTranslationsDefinitionEntry(entry);
69
+
70
+ return entry;
71
+ });
72
+
73
+ return new this(entries);
74
+ }
75
+
76
+ private constructor(entries: readonly ItextTranslationsDefinitionEntry[]) {
77
+ super(entries);
78
+ }
79
+ }
@@ -1,4 +1,5 @@
1
1
  import type { ValueType } from '../../client/ValueType.ts';
2
+ import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
2
3
  import {
3
4
  NamespaceDeclarationMap,
4
5
  type NamedSubtreeDefinition,
@@ -19,14 +20,12 @@ export class LeafNodeDefinition<V extends ValueType = ValueType>
19
20
  readonly namespaceDeclarations: NamespaceDeclarationMap;
20
21
  readonly qualifiedName: QualifiedName;
21
22
  readonly children = null;
22
- readonly instances = null;
23
- readonly defaultValue: string;
24
23
 
25
24
  constructor(
26
25
  parent: ParentNodeDefinition,
27
26
  bind: BindDefinition,
28
27
  bodyElement: AnyBodyElementDefinition | null,
29
- readonly node: Element
28
+ readonly template: StaticLeafElement
30
29
  ) {
31
30
  if (bodyElement != null && bodyElement.category !== 'control') {
32
31
  throw new Error(`Unexpected body element for nodeset ${bind.nodeset}`);
@@ -35,9 +34,8 @@ export class LeafNodeDefinition<V extends ValueType = ValueType>
35
34
  super(parent, bind, bodyElement);
36
35
 
37
36
  this.valueType = bind.type.resolved satisfies ValueType as V;
38
- this.qualifiedName = new QualifiedName(node);
37
+ this.qualifiedName = template.qualifiedName;
39
38
  this.namespaceDeclarations = new NamespaceDeclarationMap(this);
40
- this.defaultValue = node.textContent ?? '';
41
39
  }
42
40
 
43
41
  toJSON() {