@getodk/xforms-engine 0.4.0 → 0.5.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 (285) hide show
  1. package/dist/client/BaseNode.d.ts +14 -3
  2. package/dist/client/BaseValueNode.d.ts +32 -0
  3. package/dist/client/EngineConfig.d.ts +49 -48
  4. package/dist/client/InputNode.d.ts +53 -0
  5. package/dist/client/ModelValueNode.d.ts +12 -7
  6. package/dist/client/NoteNode.d.ts +2 -2
  7. package/dist/client/RootNode.d.ts +34 -7
  8. package/dist/client/SelectNode.d.ts +2 -2
  9. package/dist/client/ValueType.d.ts +3 -0
  10. package/dist/client/constants.d.ts +50 -0
  11. package/dist/client/hierarchy.d.ts +4 -4
  12. package/dist/client/identity.d.ts +14 -0
  13. package/dist/client/node-types.d.ts +2 -1
  14. package/dist/client/resources.d.ts +93 -0
  15. package/dist/client/submission/SubmissionData.d.ts +7 -0
  16. package/dist/client/submission/SubmissionDefinition.d.ts +14 -0
  17. package/dist/client/submission/SubmissionInstanceFile.d.ts +6 -0
  18. package/dist/client/submission/SubmissionOptions.d.ts +23 -0
  19. package/dist/client/submission/SubmissionResult.d.ts +91 -0
  20. package/dist/client/submission/SubmissionState.d.ts +12 -0
  21. package/dist/client/validation.d.ts +2 -2
  22. package/dist/error/ErrorProductionDesignPendingError.d.ts +7 -0
  23. package/dist/error/ValueTypeInvariantError.d.ts +17 -0
  24. package/dist/error/XPathFunctionalityError.d.ts +14 -0
  25. package/dist/error/XPathFunctionalityNotSupportedError.d.ts +7 -0
  26. package/dist/error/XPathFunctionalityPendingError.d.ts +7 -0
  27. package/dist/index.d.ts +10 -1
  28. package/dist/index.js +10856 -8585
  29. package/dist/index.js.map +1 -1
  30. package/dist/instance/Group.d.ts +9 -4
  31. package/dist/instance/InputControl.d.ts +36 -0
  32. package/dist/instance/ModelValue.d.ts +16 -26
  33. package/dist/instance/Note.d.ts +10 -3
  34. package/dist/instance/PrimaryInstance.d.ts +84 -0
  35. package/dist/instance/Root.d.ts +29 -25
  36. package/dist/instance/SelectField.d.ts +10 -2
  37. package/dist/instance/Subtree.d.ts +10 -5
  38. package/dist/instance/TriggerControl.d.ts +10 -3
  39. package/dist/instance/abstract/DescendantNode.d.ts +31 -23
  40. package/dist/instance/abstract/InstanceNode.d.ts +49 -29
  41. package/dist/instance/abstract/UnsupportedControl.d.ts +10 -3
  42. package/dist/instance/abstract/ValueNode.d.ts +48 -0
  43. package/dist/instance/hierarchy.d.ts +9 -8
  44. package/dist/instance/identity.d.ts +2 -7
  45. package/dist/instance/internal-api/EvaluationContext.d.ts +53 -12
  46. package/dist/instance/internal-api/InstanceConfig.d.ts +8 -2
  47. package/dist/instance/internal-api/InstanceValueContext.d.ts +20 -0
  48. package/dist/instance/internal-api/PrimaryInstanceDocument.d.ts +36 -0
  49. package/dist/instance/internal-api/TranslationContext.d.ts +3 -2
  50. package/dist/instance/internal-api/ValidationContext.d.ts +3 -4
  51. package/dist/instance/internal-api/ValueContext.d.ts +2 -1
  52. package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +14 -0
  53. package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +31 -0
  54. package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +18 -0
  55. package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +17 -0
  56. package/dist/instance/repeat/BaseRepeatRange.d.ts +39 -83
  57. package/dist/instance/repeat/RepeatInstance.d.ts +11 -29
  58. package/dist/instance/repeat/RepeatRangeControlled.d.ts +2 -2
  59. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +2 -2
  60. package/dist/instance/resource.d.ts +1 -1
  61. package/dist/instance/text/TextRange.d.ts +1 -1
  62. package/dist/instance/unsupported/RangeControl.d.ts +3 -1
  63. package/dist/instance/unsupported/RankControl.d.ts +3 -1
  64. package/dist/instance/unsupported/UploadControl.d.ts +3 -1
  65. package/dist/integration/xpath/EngineXPathEvaluator.d.ts +14 -0
  66. package/dist/integration/xpath/adapter/XFormsXPathNode.d.ts +71 -0
  67. package/dist/integration/xpath/adapter/engineDOMAdapter.d.ts +5 -0
  68. package/dist/integration/xpath/adapter/kind.d.ts +32 -0
  69. package/dist/integration/xpath/adapter/names.d.ts +16 -0
  70. package/dist/integration/xpath/adapter/traversal.d.ts +25 -0
  71. package/dist/integration/xpath/adapter/values.d.ts +2 -0
  72. package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +19 -0
  73. package/dist/integration/xpath/static-dom/StaticDocument.d.ts +16 -0
  74. package/dist/integration/xpath/static-dom/StaticElement.d.ts +40 -0
  75. package/dist/integration/xpath/static-dom/StaticNamedNode.d.ts +17 -0
  76. package/dist/integration/xpath/static-dom/StaticNode.d.ts +33 -0
  77. package/dist/integration/xpath/static-dom/StaticText.d.ts +16 -0
  78. package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +3 -0
  79. package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +3 -0
  80. package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +4 -0
  81. package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +4 -0
  82. package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +3 -0
  83. package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +8 -0
  84. package/dist/lib/codecs/DecimalValueCodec.d.ts +6 -0
  85. package/dist/lib/codecs/IntValueCodec.d.ts +6 -0
  86. package/dist/lib/codecs/StringValueCodec.d.ts +4 -0
  87. package/dist/lib/codecs/ValueCodec.d.ts +30 -0
  88. package/dist/lib/codecs/ValueTypePlaceholderCodec.d.ts +12 -0
  89. package/dist/lib/codecs/getSharedValueCodec.d.ts +47 -0
  90. package/dist/lib/dom/query.d.ts +3 -0
  91. package/dist/lib/reactivity/createChildrenState.d.ts +7 -5
  92. package/dist/lib/reactivity/createComputedExpression.d.ts +18 -5
  93. package/dist/lib/reactivity/createInstanceValueState.d.ts +40 -0
  94. package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +2 -2
  95. package/dist/lib/reactivity/createTranslationState.d.ts +19 -0
  96. package/dist/lib/reactivity/createValueState.d.ts +6 -10
  97. package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +4 -4
  98. package/dist/lib/xml-serialization.d.ts +41 -0
  99. package/dist/parse/XFormDOM.d.ts +18 -7
  100. package/dist/parse/XFormDefinition.d.ts +1 -2
  101. package/dist/parse/attachments/FormAttachmentResource.d.ts +27 -0
  102. package/dist/parse/body/BodyDefinition.d.ts +3 -3
  103. package/dist/parse/body/RepeatElementDefinition.d.ts +1 -1
  104. package/dist/parse/body/appearance/inputAppearanceParser.d.ts +1 -1
  105. package/dist/parse/body/control/{InputDefinition.d.ts → InputControlDefinition.d.ts} +1 -1
  106. package/dist/parse/body/control/select/ItemsetNodesetContext.d.ts +0 -2
  107. package/dist/parse/expression/abstract/DependencyContext.d.ts +0 -5
  108. package/dist/parse/expression/abstract/DependentExpression.d.ts +2 -3
  109. package/dist/parse/model/BindDefinition.d.ts +4 -5
  110. package/dist/parse/model/BindTypeDefinition.d.ts +20 -0
  111. package/dist/parse/model/DescendentNodeDefinition.d.ts +0 -1
  112. package/dist/parse/model/FormSubmissionDefinition.d.ts +8 -0
  113. package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +4 -0
  114. package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +8 -0
  115. package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +8 -0
  116. package/dist/parse/model/LeafNodeDefinition.d.ts +3 -1
  117. package/dist/parse/model/ModelBindMap.d.ts +1 -1
  118. package/dist/parse/model/ModelDefinition.d.ts +2 -0
  119. package/dist/parse/model/NodeDefinition.d.ts +0 -1
  120. package/dist/parse/model/NoteNodeDefinition.d.ts +4 -4
  121. package/dist/parse/model/RootDefinition.d.ts +3 -2
  122. package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +4 -0
  123. package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +7 -0
  124. package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +13 -0
  125. package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +14 -0
  126. package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +22 -0
  127. package/dist/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.d.ts +23 -0
  128. package/dist/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceSource.d.ts +9 -0
  129. package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +5 -0
  130. package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +7 -0
  131. package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +13 -0
  132. package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +12 -0
  133. package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +24 -0
  134. package/dist/parse/text/abstract/TextRangeDefinition.d.ts +0 -2
  135. package/dist/parse/xpath/semantic-analysis.d.ts +5 -0
  136. package/dist/solid.js +8174 -5921
  137. package/dist/solid.js.map +1 -1
  138. package/package.json +13 -11
  139. package/src/client/BaseNode.ts +16 -6
  140. package/src/client/BaseValueNode.ts +35 -0
  141. package/src/client/EngineConfig.ts +52 -51
  142. package/src/client/InputNode.ts +77 -0
  143. package/src/client/ModelValueNode.ts +30 -7
  144. package/src/client/NoteNode.ts +2 -2
  145. package/src/client/RootNode.ts +37 -7
  146. package/src/client/SelectNode.ts +3 -3
  147. package/src/client/ValueType.ts +4 -0
  148. package/src/client/constants.ts +67 -0
  149. package/src/client/hierarchy.ts +5 -5
  150. package/src/client/identity.ts +16 -0
  151. package/src/client/node-types.ts +12 -6
  152. package/src/client/resources.ts +118 -0
  153. package/src/client/submission/SubmissionData.ts +12 -0
  154. package/src/client/submission/SubmissionDefinition.ts +16 -0
  155. package/src/client/submission/SubmissionInstanceFile.ts +9 -0
  156. package/src/client/submission/SubmissionOptions.ts +28 -0
  157. package/src/client/submission/SubmissionResult.ts +124 -0
  158. package/src/client/submission/SubmissionState.ts +14 -0
  159. package/src/client/validation.ts +2 -2
  160. package/src/error/ErrorProductionDesignPendingError.ts +6 -0
  161. package/src/error/ValueTypeInvariantError.ts +22 -0
  162. package/src/error/XPathFunctionalityError.ts +26 -0
  163. package/src/error/XPathFunctionalityNotSupportedError.ts +18 -0
  164. package/src/error/XPathFunctionalityPendingError.ts +18 -0
  165. package/src/index.ts +10 -1
  166. package/src/instance/Group.ts +17 -5
  167. package/src/instance/InputControl.ts +119 -0
  168. package/src/instance/ModelValue.ts +47 -54
  169. package/src/instance/Note.ts +24 -8
  170. package/src/instance/PrimaryInstance.ts +244 -0
  171. package/src/instance/Root.ts +62 -134
  172. package/src/instance/SelectField.ts +56 -19
  173. package/src/instance/Subtree.ts +19 -7
  174. package/src/instance/TriggerControl.ts +23 -6
  175. package/src/instance/abstract/DescendantNode.ts +90 -45
  176. package/src/instance/abstract/InstanceNode.ts +103 -105
  177. package/src/instance/abstract/UnsupportedControl.ts +28 -5
  178. package/src/instance/abstract/ValueNode.ts +127 -0
  179. package/src/instance/children.ts +9 -10
  180. package/src/instance/hierarchy.ts +19 -15
  181. package/src/instance/identity.ts +3 -9
  182. package/src/instance/index.ts +25 -7
  183. package/src/instance/internal-api/EvaluationContext.ts +60 -13
  184. package/src/instance/internal-api/InstanceConfig.ts +9 -2
  185. package/src/instance/internal-api/InstanceValueContext.ts +24 -0
  186. package/src/instance/internal-api/PrimaryInstanceDocument.ts +53 -0
  187. package/src/instance/internal-api/TranslationContext.ts +3 -2
  188. package/src/instance/internal-api/ValidationContext.ts +3 -4
  189. package/src/instance/internal-api/ValueContext.ts +2 -1
  190. package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +20 -0
  191. package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +42 -0
  192. package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +25 -0
  193. package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +23 -0
  194. package/src/instance/repeat/BaseRepeatRange.ts +50 -131
  195. package/src/instance/repeat/RepeatInstance.ts +20 -46
  196. package/src/instance/repeat/RepeatRangeControlled.ts +5 -5
  197. package/src/instance/repeat/RepeatRangeUncontrolled.ts +2 -4
  198. package/src/instance/resource.ts +1 -1
  199. package/src/instance/text/TextChunk.ts +1 -1
  200. package/src/instance/unsupported/RangeControl.ts +5 -1
  201. package/src/instance/unsupported/RankControl.ts +5 -1
  202. package/src/instance/unsupported/UploadControl.ts +5 -1
  203. package/src/integration/xpath/EngineXPathEvaluator.ts +22 -0
  204. package/src/integration/xpath/adapter/XFormsXPathNode.ts +126 -0
  205. package/src/integration/xpath/adapter/engineDOMAdapter.ts +57 -0
  206. package/src/integration/xpath/adapter/kind.ts +114 -0
  207. package/src/integration/xpath/adapter/names.ts +99 -0
  208. package/src/integration/xpath/adapter/traversal.ts +228 -0
  209. package/src/integration/xpath/adapter/values.ts +5 -0
  210. package/src/integration/xpath/static-dom/StaticAttribute.ts +33 -0
  211. package/src/integration/xpath/static-dom/StaticDocument.ts +38 -0
  212. package/src/integration/xpath/static-dom/StaticElement.ts +106 -0
  213. package/src/integration/xpath/static-dom/StaticNamedNode.ts +45 -0
  214. package/src/integration/xpath/static-dom/StaticNode.ts +68 -0
  215. package/src/integration/xpath/static-dom/StaticText.ts +28 -0
  216. package/src/lib/client-reactivity/README.md +0 -0
  217. package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +12 -0
  218. package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +20 -0
  219. package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +17 -0
  220. package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +22 -0
  221. package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +21 -0
  222. package/src/lib/client-reactivity/submission/prepareSubmission.ts +172 -0
  223. package/src/lib/codecs/DecimalValueCodec.ts +46 -0
  224. package/src/lib/codecs/IntValueCodec.ts +100 -0
  225. package/src/lib/codecs/StringValueCodec.ts +11 -0
  226. package/src/lib/codecs/ValueCodec.ts +106 -0
  227. package/src/lib/codecs/ValueTypePlaceholderCodec.ts +19 -0
  228. package/src/lib/codecs/getSharedValueCodec.ts +77 -0
  229. package/src/lib/dom/query.ts +7 -0
  230. package/src/lib/reactivity/createChildrenState.ts +8 -6
  231. package/src/lib/reactivity/createComputedExpression.ts +57 -34
  232. package/src/lib/reactivity/createInstanceValueState.ts +166 -0
  233. package/src/lib/reactivity/createNoteReadonlyThunk.ts +12 -7
  234. package/src/lib/reactivity/createSelectItems.ts +21 -21
  235. package/src/lib/reactivity/createTranslationState.ts +61 -0
  236. package/src/lib/reactivity/createValueState.ts +62 -120
  237. package/src/lib/reactivity/materializeCurrentStateChildren.ts +7 -7
  238. package/src/lib/reactivity/text/createTextRange.ts +4 -3
  239. package/src/lib/reactivity/validation/createAggregatedViolations.ts +1 -1
  240. package/src/lib/reactivity/validation/createValidation.ts +2 -3
  241. package/src/lib/xml-serialization.ts +96 -0
  242. package/src/parse/XFormDOM.ts +110 -75
  243. package/src/parse/XFormDefinition.ts +1 -6
  244. package/src/parse/attachments/FormAttachmentResource.ts +40 -0
  245. package/src/parse/body/BodyDefinition.ts +3 -3
  246. package/src/parse/body/appearance/inputAppearanceParser.ts +1 -1
  247. package/src/parse/body/control/{InputDefinition.ts → InputControlDefinition.ts} +3 -5
  248. package/src/parse/body/control/select/ItemsetNodesetContext.ts +0 -5
  249. package/src/parse/expression/abstract/DependencyContext.ts +0 -26
  250. package/src/parse/expression/abstract/DependentExpression.ts +2 -13
  251. package/src/parse/model/BindDefinition.ts +5 -8
  252. package/src/parse/model/BindTypeDefinition.ts +175 -0
  253. package/src/parse/model/DescendentNodeDefinition.ts +0 -6
  254. package/src/parse/model/FormSubmissionDefinition.ts +44 -0
  255. package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +4 -0
  256. package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +41 -0
  257. package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +31 -0
  258. package/src/parse/model/LeafNodeDefinition.ts +4 -1
  259. package/src/parse/model/ModelBindMap.ts +6 -8
  260. package/src/parse/model/ModelDefinition.ts +6 -1
  261. package/src/parse/model/NodeDefinition.ts +0 -3
  262. package/src/parse/model/NoteNodeDefinition.ts +3 -3
  263. package/src/parse/model/RootDefinition.ts +2 -1
  264. package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +4 -0
  265. package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +12 -0
  266. package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +102 -0
  267. package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +40 -0
  268. package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +288 -0
  269. package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.ts +222 -0
  270. package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceSource.ts +22 -0
  271. package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +414 -0
  272. package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +19 -0
  273. package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +29 -0
  274. package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +32 -0
  275. package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +149 -0
  276. package/src/parse/text/abstract/TextRangeDefinition.ts +0 -6
  277. package/src/parse/xpath/semantic-analysis.ts +29 -0
  278. package/dist/client/StringNode.d.ts +0 -46
  279. package/dist/instance/StringField.d.ts +0 -44
  280. package/dist/instance/internal-api/SubscribableDependency.d.ts +0 -59
  281. package/dist/parse/XFormDataType.d.ts +0 -25
  282. package/src/client/StringNode.ts +0 -52
  283. package/src/instance/StringField.ts +0 -120
  284. package/src/instance/internal-api/SubscribableDependency.ts +0 -61
  285. package/src/parse/XFormDataType.ts +0 -62
@@ -1,17 +1,15 @@
1
1
  import { UpsertableMap } from '@getodk/common/lib/collections/UpsertableMap.ts';
2
- import type { XFormsXPathEvaluator } from '@getodk/xpath';
3
2
  import type { Accessor } from 'solid-js';
4
3
  import { createMemo } from 'solid-js';
5
4
  import type { TextRange as ClientTextRange } from '../../client/TextRange.ts';
6
- import type { SelectItem } from '../../index.ts';
5
+ import type { ActiveLanguage, SelectItem } from '../../index.ts';
6
+ import type { EvaluationContext } from '../../instance/internal-api/EvaluationContext.ts';
7
+ import type { TranslationContext } from '../../instance/internal-api/TranslationContext.ts';
7
8
  import type { SelectField } from '../../instance/SelectField.ts';
8
- import type {
9
- EvaluationContext,
10
- EvaluationContextRoot,
11
- } from '../../instance/internal-api/EvaluationContext.ts';
12
- import type { SubscribableDependency } from '../../instance/internal-api/SubscribableDependency.ts';
13
9
  import { TextChunk } from '../../instance/text/TextChunk.ts';
14
10
  import { TextRange } from '../../instance/text/TextRange.ts';
11
+ import type { EngineXPathNode } from '../../integration/xpath/adapter/kind.ts';
12
+ import type { EngineXPathEvaluator } from '../../integration/xpath/EngineXPathEvaluator.ts';
15
13
  import type { ItemDefinition } from '../../parse/body/control/select/ItemDefinition.ts';
16
14
  import type { ItemsetDefinition } from '../../parse/body/control/select/ItemsetDefinition.ts';
17
15
  import { createComputedExpression } from './createComputedExpression.ts';
@@ -20,8 +18,8 @@ import { createTextRange } from './text/createTextRange.ts';
20
18
 
21
19
  type DerivedItemLabel = ClientTextRange<'item-label', 'form-derived'>;
22
20
 
23
- const derivedItemLabel = (context: EvaluationContext, value: string): DerivedItemLabel => {
24
- const chunk = new TextChunk(context.root, 'literal', value);
21
+ const derivedItemLabel = (context: TranslationContext, value: string): DerivedItemLabel => {
22
+ const chunk = new TextChunk(context, 'literal', value);
25
23
 
26
24
  return new TextRange('form-derived', 'item-label', [chunk]);
27
25
  };
@@ -61,23 +59,21 @@ const createTranslatedStaticSelectItems = (
61
59
  };
62
60
 
63
61
  class ItemsetItemEvaluationContext implements EvaluationContext {
62
+ readonly isAttached: Accessor<boolean>;
64
63
  readonly scope: ReactiveScope;
65
- readonly evaluator: XFormsXPathEvaluator;
66
- readonly root: EvaluationContextRoot;
64
+ readonly evaluator: EngineXPathEvaluator;
67
65
  readonly contextReference: Accessor<string>;
66
+ readonly getActiveLanguage: Accessor<ActiveLanguage>;
68
67
 
69
68
  constructor(
70
- private readonly selectField: SelectField,
71
- readonly contextNode: Node
69
+ selectField: SelectField,
70
+ readonly contextNode: EngineXPathNode
72
71
  ) {
72
+ this.isAttached = selectField.isAttached;
73
73
  this.scope = selectField.scope;
74
74
  this.evaluator = selectField.evaluator;
75
- this.root = selectField.root;
76
75
  this.contextReference = selectField.contextReference;
77
- }
78
-
79
- getSubscribableDependenciesByReference(reference: string): readonly SubscribableDependency[] {
80
- return this.selectField.getSubscribableDependenciesByReference(reference);
76
+ this.getActiveLanguage = selectField.getActiveLanguage;
81
77
  }
82
78
  }
83
79
 
@@ -107,14 +103,18 @@ const createItemsetItems = (
107
103
  itemset: ItemsetDefinition
108
104
  ): Accessor<readonly ItemsetItem[]> => {
109
105
  return selectField.scope.runTask(() => {
110
- const itemNodes = createComputedExpression(selectField, itemset.nodes);
111
- const itemsCache = new UpsertableMap<Node, ItemsetItem>();
106
+ const itemNodes = createComputedExpression(selectField, itemset.nodes, {
107
+ defaultValue: [],
108
+ });
109
+ const itemsCache = new UpsertableMap<EngineXPathNode, ItemsetItem>();
112
110
 
113
111
  return createMemo(() => {
114
112
  return itemNodes().map((itemNode) => {
115
113
  return itemsCache.upsert(itemNode, () => {
116
114
  const context = new ItemsetItemEvaluationContext(selectField, itemNode);
117
- const value = createComputedExpression(context, itemset.value);
115
+ const value = createComputedExpression(context, itemset.value, {
116
+ defaultValue: '',
117
+ });
118
118
  const label = createSelectItemsetItemLabel(context, itemset, value);
119
119
 
120
120
  return {
@@ -0,0 +1,61 @@
1
+ import type { XFormsXPathEvaluator } from '@getodk/xpath';
2
+ import type { Accessor } from 'solid-js';
3
+ import { createComputed, createSignal } from 'solid-js';
4
+ import type { ActiveLanguage, FormLanguage, FormLanguages } from '../../client/FormLanguage.ts';
5
+ import type { EngineXPathEvaluator } from '../../integration/xpath/EngineXPathEvaluator.ts';
6
+ import type { ReactiveScope } from './scope.ts';
7
+ import type { SimpleAtomicStateSetter } from './types.ts';
8
+
9
+ interface TranslationState {
10
+ readonly languages: FormLanguages;
11
+ readonly getActiveLanguage: Accessor<ActiveLanguage>;
12
+ readonly setActiveLanguage: SimpleAtomicStateSetter<FormLanguage>;
13
+ }
14
+
15
+ /**
16
+ * @todo It's been very silly all along that {@link XFormsXPathEvaluator} is
17
+ * responsible for parsing translation languages, and maintaining the active
18
+ * language state. It is especially silly now that we've moved _part of the
19
+ * parsing_ up to the constructor call site. Let's finish off that awkwardness
20
+ * in a subsequent refactor.
21
+ */
22
+ export const createTranslationState = (
23
+ scope: ReactiveScope,
24
+ evaluator: EngineXPathEvaluator
25
+ ): TranslationState => {
26
+ const activeLanguageName = evaluator.getActiveLanguage();
27
+ const languageNames = evaluator.getLanguages();
28
+
29
+ let defaultLanguage: ActiveLanguage;
30
+ let languages: FormLanguages;
31
+
32
+ if (activeLanguageName == null) {
33
+ defaultLanguage = { isSyntheticDefault: true, language: '' };
34
+ languages = [defaultLanguage];
35
+ } else {
36
+ const inactiveLanguages = languageNames
37
+ .filter((languageName) => languageName !== activeLanguageName)
38
+ .map((language) => ({ language }));
39
+
40
+ defaultLanguage = { language: activeLanguageName };
41
+ languages = [defaultLanguage, ...inactiveLanguages];
42
+ }
43
+
44
+ const [getActiveLanguage, baseSetActiveLanguage] = createSignal(defaultLanguage);
45
+
46
+ const setActiveLanguage: SimpleAtomicStateSetter<FormLanguage> = (value) => {
47
+ return baseSetActiveLanguage(value);
48
+ };
49
+
50
+ scope.runTask(() => {
51
+ createComputed(() => {
52
+ evaluator.setActiveLanguage(getActiveLanguage().language);
53
+ });
54
+ });
55
+
56
+ return {
57
+ languages,
58
+ getActiveLanguage,
59
+ setActiveLanguage,
60
+ };
61
+ };
@@ -1,8 +1,7 @@
1
- import { createComputed, createMemo, createSignal, untrack } from 'solid-js';
2
- import type { SubscribableDependency } from '../../instance/internal-api/SubscribableDependency.ts';
1
+ import { createComputed, createMemo, createSignal, untrack, type Signal } from 'solid-js';
2
+ import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
3
3
  import type { ValueContext } from '../../instance/internal-api/ValueContext.ts';
4
4
  import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
5
- import type { DependentExpression } from '../../parse/expression/abstract/DependentExpression.ts';
6
5
  import { createComputedExpression } from './createComputedExpression.ts';
7
6
  import type { SimpleAtomicState, SimpleAtomicStateSetter } from './types.ts';
8
7
 
@@ -19,8 +18,7 @@ export interface ValueStateOptions {
19
18
  * other words, this value should not be used for edits.
20
19
  *
21
20
  * - 'PRIMARY_INSTANCE': Derives the initial state from the current text
22
- * content of the {@link ValueNode.contextNode} (currently an XML DOM
23
- * backing store/source of thruth for primary instance state). This option
21
+ * content of the {@link ValueNode.contextNode}. This option
24
22
  * should be specified when initializing a form with existing primary
25
23
  * instance data, such as when editing a previous submission.
26
24
  *
@@ -33,110 +31,54 @@ export interface ValueStateOptions {
33
31
  readonly initialValueSource?: InitialValueSource;
34
32
  }
35
33
 
36
- interface PersistedValueState {
37
- readonly isRelevant: boolean;
38
- readonly value: string;
39
- }
40
-
41
- type PrimaryInstanceValueState = SimpleAtomicState<string>;
42
-
43
- type ValueState<RuntimeValue> = SimpleAtomicState<RuntimeValue>;
44
-
45
- /**
46
- * Creates a signal which:
47
- *
48
- * 1. Persists its state to the primary instance's
49
- * {@link ValueContext.contextNode | contextNode} on state changes.
50
- * 2. Propagates downstream reactivity only after that write is persisted.
51
- *
52
- * This ensures that reactive subscriptions get a consistent view of a node's
53
- * current state, regardless of whether they derive state from values in the
54
- * primary instance (currently: computed {@link DependentExpression}
55
- * evaluations) or from other aspects of reactive runtime state (generally,
56
- * everything besides computed {@link DependentExpression}s).
57
- */
58
- const createPrimaryInstanceValueState = <RuntimeValue>(
34
+ const getInitialValue = <RuntimeValue>(
59
35
  context: ValueContext<RuntimeValue>,
60
36
  options: ValueStateOptions
61
- ): PrimaryInstanceValueState => {
62
- const { contextNode, definition, scope } = context;
63
- const { initialValueSource } = options;
64
- const { defaultValue } = definition;
37
+ ): string => {
38
+ const { initialValueSource = 'FORM_DEFAULT' } = options;
65
39
 
66
- return scope.runTask(() => {
67
- // prettier-ignore
68
- const initialValue =
69
- initialValueSource === 'PRIMARY_INSTANCE'
70
- ? contextNode.textContent ?? defaultValue
71
- : defaultValue;
40
+ if (initialValueSource === 'FORM_DEFAULT') {
41
+ return context.definition.defaultValue;
42
+ }
72
43
 
73
- const persistedValueState = createSignal<PersistedValueState>(
74
- {
75
- isRelevant: context.isRelevant(),
76
- value: initialValue,
77
- },
78
- {
79
- // This could return a single boolean expression, but checking each
80
- // equality condition separately feels like it more clearly expresses
81
- // the intent.
82
- equals: (previous, updated) => {
83
- if (updated.isRelevant !== previous.isRelevant) {
84
- return false;
85
- }
44
+ throw new ErrorProductionDesignPendingError('Edit implementation pending');
45
+ };
86
46
 
87
- return updated.value === previous.value;
88
- },
89
- }
90
- );
91
- const [persistedValue, setValueForPersistence] = persistedValueState;
47
+ type BaseValueState = Signal<string>;
92
48
 
93
- createComputed(() => {
94
- const isRelevant = context.isRelevant();
49
+ type RelevantValueState = SimpleAtomicState<string>;
95
50
 
96
- setValueForPersistence((persisted) => {
97
- return {
98
- isRelevant,
99
- value: persisted.value,
100
- };
101
- });
102
- });
51
+ /**
52
+ * Wraps {@link baseValueState} in a signal-like interface which:
53
+ *
54
+ * - produces a blank value for nodes ({@link context}) in a non-relevant state
55
+ * - persists, and restores, the most recent non-blank value state when a
56
+ * node/context's relevance is restored
57
+ */
58
+ const createRelevantValueState = <RuntimeValue>(
59
+ context: ValueContext<RuntimeValue>,
60
+ baseValueState: BaseValueState
61
+ ): RelevantValueState => {
62
+ return context.scope.runTask(() => {
63
+ const [getRelevantValue, setValue] = baseValueState;
103
64
 
104
- const toSignalValue = (current: PersistedValueState): string => {
105
- if (current.isRelevant) {
106
- return current.value;
65
+ const getValue = createMemo(() => {
66
+ if (context.isRelevant()) {
67
+ return getRelevantValue();
107
68
  }
108
69
 
109
70
  return '';
110
- };
111
-
112
- const [signalValue, setSignalValue] = createSignal(toSignalValue(persistedValue()));
113
-
114
- createComputed(() => {
115
- const { isRelevant, value } = persistedValue();
116
- const preparedTextContent = isRelevant ? value : '';
117
- const assignedTextContent = (contextNode.textContent = preparedTextContent);
118
-
119
- setSignalValue(assignedTextContent);
120
71
  });
121
72
 
122
- const setPrimaryInstanceValue: SimpleAtomicStateSetter<string> = (value) => {
123
- // TODO: Check (error?) for non-relevant value change?
124
- const persisted = setValueForPersistence({
125
- isRelevant: context.isRelevant(),
126
- value,
127
- });
128
-
129
- return persisted.value;
130
- };
131
-
132
- return [signalValue, setPrimaryInstanceValue];
73
+ return [getValue, setValue];
133
74
  });
134
75
  };
135
76
 
77
+ type RuntimeValueState<RuntimeValue> = SimpleAtomicState<RuntimeValue>;
78
+
136
79
  /**
137
- * Wraps a node's {@link PrimaryInstanceValueState} in a signal-like interface
138
- * which automatically encodes and decodes a node's runtime value
139
- * representation:
80
+ * Wraps {@link relevantValueState} in a signal-like interface which
81
+ * automatically encodes and decodes a node's runtime value representation:
140
82
  *
141
83
  * - Values read by a node will be read from the current state as persisted in
142
84
  * the primary instance, then {@link ValueContext.decodeValue | decoded} (as
@@ -144,21 +86,17 @@ const createPrimaryInstanceValueState = <RuntimeValue>(
144
86
  * functionality provided by that node.
145
87
  *
146
88
  * - Values written by a node will be {@link ValueContext.encodeValue | encoded}
147
- * (also as implemented by that node) into a string appropriate to persist to
148
- * the primary instance, and written to it as such.
149
- *
150
- * - Downstream reactive computations should subscribe to updates to this
151
- * runtime state (suggesting the value node itself should access this state in
152
- * its {@link SubscribableDependency.subscribe} implementation).
89
+ * (also as implemented by that node) into a string value appropriate for
90
+ * serialization in an instance submission.
153
91
  */
154
92
  const createRuntimeValueState = <RuntimeValue>(
155
93
  context: ValueContext<RuntimeValue>,
156
- primaryInstanceState: PrimaryInstanceValueState
157
- ): ValueState<RuntimeValue> => {
94
+ relevantValueState: RelevantValueState
95
+ ): RuntimeValueState<RuntimeValue> => {
158
96
  const { decodeValue, encodeValue } = context;
159
97
 
160
98
  return context.scope.runTask(() => {
161
- const [primaryInstanceValue, setPrimaryInstanceValue] = primaryInstanceState;
99
+ const [primaryInstanceValue, setPrimaryInstanceValue] = relevantValueState;
162
100
  const getRuntimeValue = createMemo(() => {
163
101
  return decodeValue(primaryInstanceValue());
164
102
  });
@@ -212,10 +150,12 @@ const createCalculation = <RuntimeValue>(
212
150
  calculateDefinition: BindComputationExpression<'calculate'>
213
151
  ): void => {
214
152
  context.scope.runTask(() => {
215
- const calculate = createComputedExpression(context, calculateDefinition);
153
+ const calculate = createComputedExpression(context, calculateDefinition, {
154
+ defaultValue: '',
155
+ });
216
156
 
217
157
  createComputed(() => {
218
- if (context.isRelevant()) {
158
+ if (context.isAttached() && context.isRelevant()) {
219
159
  const calculated = calculate();
220
160
  const value = context.decodeValue(calculated);
221
161
 
@@ -225,34 +165,36 @@ const createCalculation = <RuntimeValue>(
225
165
  });
226
166
  };
227
167
 
168
+ type ValueState<RuntimeValue> = SimpleAtomicState<RuntimeValue>;
169
+
228
170
  /**
229
171
  * Provides a consistent interface for value nodes of any type which:
230
172
  *
231
- * - derives initial state from either the existing primary instance state (e.g.
232
- * for edits) or the node's definition (e.g. initializing a new submission)
233
- * - decodes primary instance state into the value node's runtime type
234
- * - encodes and persists updated values to the primary instance
173
+ * - derives initial state from either an existing instance (e.g. for edits) or
174
+ * the node's definition (e.g. initializing a new submission)
175
+ * - decodes current primary instance state into the value node's runtime type
176
+ * - encodes updated runtime values to store updated instance state
235
177
  * - initializes reactive computation of `calculate` bind expressions for those
236
178
  * nodes defined with one
237
- * - ensures any downstream reactive dependencies are updated only after writes
238
- * (whether performed by a client, or by a reactive `calculate` computation)
239
- * are persisted, ensuring a consistent view of state when downstream
240
- * computations perform XPath evaluations against that primary instance state
179
+ * - prevents downstream writes to nodes in a readonly state
241
180
  */
242
181
  export const createValueState = <RuntimeValue>(
243
182
  context: ValueContext<RuntimeValue>,
244
183
  options: ValueStateOptions = {}
245
184
  ): ValueState<RuntimeValue> => {
246
- const primaryInstanceState = createPrimaryInstanceValueState(context, options);
247
- const runtimeState = createRuntimeValueState(context, primaryInstanceState);
248
-
249
- const { calculate } = context.definition.bind;
185
+ return context.scope.runTask(() => {
186
+ const initialValue = getInitialValue(context, options);
187
+ const baseValueState = createSignal(initialValue);
188
+ const valueState = createRelevantValueState(context, baseValueState);
189
+ const runtimeState = createRuntimeValueState(context, valueState);
190
+ const { calculate } = context.definition.bind;
250
191
 
251
- if (calculate != null) {
252
- const [, setValue] = runtimeState;
192
+ if (calculate != null) {
193
+ const [, setValue] = runtimeState;
253
194
 
254
- createCalculation(context, setValue, calculate);
255
- }
195
+ createCalculation(context, setValue, calculate);
196
+ }
256
197
 
257
- return guardDownstreamReadonlyWrites(context, runtimeState);
198
+ return guardDownstreamReadonlyWrites(context, runtimeState);
199
+ });
258
200
  };
@@ -1,13 +1,13 @@
1
+ import type { FormNodeID } from '../../client/identity.ts';
1
2
  import type { AnyChildNode } from '../../instance/hierarchy.ts';
2
- import type { NodeID } from '../../instance/identity.ts';
3
3
  import type { ChildrenState, createChildrenState } from './createChildrenState.ts';
4
4
  import type { ClientState } from './node-state/createClientState.ts';
5
5
  import type { CurrentState } from './node-state/createCurrentState.ts';
6
6
  import type { ReactiveScope } from './scope.ts';
7
7
 
8
8
  interface InconsistentChildrenStateDetails {
9
- readonly missingIds: readonly NodeID[];
10
- readonly unexpectedIds: readonly NodeID[];
9
+ readonly missingIds: readonly FormNodeID[];
10
+ readonly unexpectedIds: readonly FormNodeID[];
11
11
  }
12
12
 
13
13
  class InconsistentChildrenStateError extends Error {
@@ -37,7 +37,7 @@ class InconsistentChildrenStateError extends Error {
37
37
  }
38
38
 
39
39
  export interface EncodedParentState {
40
- readonly children: readonly NodeID[];
40
+ readonly children: readonly FormNodeID[];
41
41
  }
42
42
 
43
43
  /**
@@ -58,7 +58,7 @@ export interface EncodedParentState {
58
58
  * @todo should we throw rather than warn until we have this confidence?
59
59
  */
60
60
  const reportInconsistentChildrenState = (
61
- expectedClientIds: readonly NodeID[],
61
+ expectedClientIds: readonly FormNodeID[],
62
62
  actualNodes: readonly AnyChildNode[]
63
63
  ): void => {
64
64
  const actualIds = actualNodes.map((node) => node.nodeId);
@@ -88,8 +88,8 @@ export type MaterializedChildren<
88
88
  /**
89
89
  * Creates a wrapper proxy around a parent node's {@link CurrentState} to map
90
90
  * `children` state, which is written to the node's (internal, synchronized)
91
- * {@link ClientState} as an array of {@link NodeID}s, back to the node objects
92
- * corresponding to those IDs.
91
+ * {@link ClientState} as an array of {@link FormNodeID}s, back to the node
92
+ * objects corresponding to those IDs.
93
93
  *
94
94
  * @see {@link createChildrenState} for further detail.
95
95
  */
@@ -29,7 +29,9 @@ const createComputedTextChunk = (
29
29
  }
30
30
 
31
31
  return context.scope.runTask(() => {
32
- const getText = createComputedExpression(context, textSource);
32
+ const getText = createComputedExpression(context, textSource, {
33
+ defaultValue: '',
34
+ });
33
35
 
34
36
  return {
35
37
  source,
@@ -43,14 +45,13 @@ const createTextChunks = (
43
45
  textSources: readonly AnyTextChunkExpression[]
44
46
  ): Accessor<readonly TextChunk[]> => {
45
47
  return context.scope.runTask(() => {
46
- const { root } = context;
47
48
  const chunkComputations = textSources.map((textSource) => {
48
49
  return createComputedTextChunk(context, textSource);
49
50
  });
50
51
 
51
52
  return createMemo(() => {
52
53
  return chunkComputations.map(({ source, getText }) => {
53
- return new TextChunk(root, source, getText());
54
+ return new TextChunk(context, source, getText());
54
55
  });
55
56
  });
56
57
  });
@@ -32,8 +32,8 @@ const collectViolationReferences = (
32
32
  return context.getChildren().flatMap((child) => {
33
33
  switch (child.nodeType) {
34
34
  case 'model-value':
35
+ case 'input':
35
36
  case 'note':
36
- case 'string':
37
37
  case 'select':
38
38
  case 'range':
39
39
  case 'rank':
@@ -33,7 +33,7 @@ const engineViolationMessage = <Role extends ValidationTextRole>(
33
33
  role: Role
34
34
  ): Accessor<EngineViolationMessage<Role>> => {
35
35
  const messageText = VALIDATION_TEXT[role];
36
- const chunk = new TextChunk(context.root, 'literal', messageText);
36
+ const chunk = new TextChunk(context, 'literal', messageText);
37
37
  const message = new TextRange('engine', role, [chunk]);
38
38
 
39
39
  return () => message;
@@ -75,9 +75,8 @@ const createConstraintValidation = (
75
75
  }
76
76
 
77
77
  const isValid = createComputedExpression(context, constraint, {
78
- arbitraryDependencies: [context],
78
+ defaultValue: true,
79
79
  });
80
-
81
80
  const message = createViolationMessage(context, 'constraintMsg', constraintMsg);
82
81
 
83
82
  return createMemo(() => {
@@ -0,0 +1,96 @@
1
+ declare const ESCAPED_XML_TEXT_BRAND: unique symbol;
2
+
3
+ export type EscapedXMLText = string & { readonly [ESCAPED_XML_TEXT_BRAND]: true };
4
+
5
+ const ATTR_REGEX = /[&<>"]/;
6
+ const CONTENT_REGEX = /[&<>]/;
7
+
8
+ /**
9
+ * This is based on the `escapeHTML` implementation in
10
+ * {@link https://github.com/ryansolid/dom-expressions} (Solid's JSX transform).
11
+ *
12
+ * @see {@link https://github.com/ryansolid/dom-expressions/pull/27} for
13
+ * motivation to derive this implementation approach.
14
+ *
15
+ * The intent is that this can be updated easily if the base implementation
16
+ * changes. As such, some aspects of this implementation differ from some of our
17
+ * typical code style preferences.
18
+ *
19
+ * Notable changes from the base implementation:
20
+ *
21
+ * - Formatting: automated only.
22
+ * - Naming: the {@link text} parameter is named `html` in the base
23
+ * implementation. That would be confusing if preserved.
24
+ * - Types:
25
+ * - Parameter types are added (of course)
26
+ * - Return type is branded as {@link EscapedXMLText}, to allow downstream
27
+ * checks that escaping has been performed. Return statements are cast
28
+ * accordingly.
29
+ * - {@link text} attempts to minimize risk of double-escaping by excluding
30
+ * that same branded type.
31
+ * - The '>' character is also escaped, necessary for producing valid XML.
32
+ *
33
+ * As with the base implementation, we leave some characters unescaped:
34
+ *
35
+ * - " (double quote): except when {@link attr} is `true`.
36
+ *
37
+ * - ' (single quote): on the assumption that attributes are always serialized
38
+ * in double quotes. If we ever move this to `@getodk/common`, we'd want to
39
+ * reconsider this assumption.
40
+ */
41
+ export const escapeXMLText = <Text extends string>(
42
+ text: Exclude<Text, EscapedXMLText>,
43
+ attr?: boolean
44
+ ): EscapedXMLText => {
45
+ const match = (attr ? ATTR_REGEX : CONTENT_REGEX).exec(text);
46
+ if (!match) return text as string as EscapedXMLText;
47
+ let index = 0;
48
+ let lastIndex = 0;
49
+ let out = '';
50
+ let escape = '';
51
+ for (index = match.index; index < text.length; index++) {
52
+ switch (text.charCodeAt(index)) {
53
+ case 34: // "
54
+ if (!attr) continue;
55
+ escape = '&quot;';
56
+ break;
57
+ case 38: // &
58
+ escape = '&amp;';
59
+ break;
60
+ case 60: // <
61
+ escape = '&lt;';
62
+ break;
63
+ case 62: // >
64
+ escape = '&gt;';
65
+ break;
66
+ default:
67
+ continue;
68
+ }
69
+ if (lastIndex !== index) out += text.substring(lastIndex, index);
70
+ lastIndex = index + 1;
71
+ out += escape;
72
+ }
73
+ return lastIndex !== index
74
+ ? ((out + text.substring(lastIndex, index)) as EscapedXMLText)
75
+ : (out as EscapedXMLText);
76
+ };
77
+
78
+ const serializeElementXML = (nodeName: string, children: string): string => {
79
+ if (children === '') {
80
+ return `<${nodeName}/>`;
81
+ }
82
+
83
+ // TODO: attributes
84
+ return `<${nodeName}>${children}</${nodeName}>`;
85
+ };
86
+
87
+ export const serializeParentElementXML = (
88
+ nodeName: string,
89
+ serializedChildren: readonly string[]
90
+ ): string => {
91
+ return serializeElementXML(nodeName, serializedChildren.join(''));
92
+ };
93
+
94
+ export const serializeLeafElementXML = (nodeName: string, xmlValue: EscapedXMLText): string => {
95
+ return serializeElementXML(nodeName, xmlValue.normalize());
96
+ };