@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
@@ -0,0 +1,106 @@
1
+ import type { Accessor } from 'solid-js';
2
+ import type { ValueType } from '../../client/ValueType.ts';
3
+ import type { DecodeInstanceValue } from '../../instance/internal-api/InstanceValueContext.ts';
4
+ import type { SimpleAtomicState } from '../reactivity/types.ts';
5
+
6
+ type CodecEncoder<RuntimeInputValue> = (input: RuntimeInputValue) => string;
7
+
8
+ type CodecDecoder<RuntimeValue> = (value: string) => RuntimeValue;
9
+
10
+ type RuntimeValueAccessor<RuntimeValue> = Accessor<RuntimeValue>;
11
+
12
+ export type RuntimeValueSetter<
13
+ RuntimeValue extends RuntimeInputValue,
14
+ RuntimeInputValue = RuntimeValue,
15
+ > = (input: RuntimeInputValue) => RuntimeValue;
16
+
17
+ export type RuntimeValueState<
18
+ RuntimeValue extends RuntimeInputValue,
19
+ RuntimeInputValue = RuntimeValue,
20
+ > = readonly [
21
+ get: RuntimeValueAccessor<RuntimeValue>,
22
+ set: RuntimeValueSetter<RuntimeValue, RuntimeInputValue>,
23
+ ];
24
+
25
+ export type CreateRuntimeValueState<
26
+ RuntimeValue extends RuntimeInputValue,
27
+ RuntimeInputValue = RuntimeValue,
28
+ > = (
29
+ instanceState: SimpleAtomicState<string>
30
+ ) => RuntimeValueState<RuntimeValue, RuntimeInputValue>;
31
+
32
+ type RuntimeValueStateFactory<
33
+ RuntimeValue extends RuntimeInputValue,
34
+ RuntimeInputValue = RuntimeValue,
35
+ > = (
36
+ encodeValue: CodecEncoder<RuntimeInputValue>,
37
+ decodeValue: CodecDecoder<RuntimeValue>
38
+ ) => CreateRuntimeValueState<RuntimeValue, RuntimeInputValue>;
39
+
40
+ type DecodeInstanceValueFactory<
41
+ RuntimeValue extends RuntimeInputValue,
42
+ RuntimeInputValue = RuntimeValue,
43
+ > = (
44
+ encodeValue: CodecEncoder<RuntimeInputValue>,
45
+ decodeValue: CodecDecoder<RuntimeValue>
46
+ ) => DecodeInstanceValue;
47
+
48
+ interface ValueCodecOptions<RuntimeValue extends RuntimeInputValue, RuntimeInputValue> {
49
+ readonly decodeInstanceValueFactory?: DecodeInstanceValueFactory<RuntimeValue, RuntimeInputValue>;
50
+ readonly runtimeValueStateFactory?: RuntimeValueStateFactory<RuntimeValue, RuntimeInputValue>;
51
+ }
52
+
53
+ export abstract class ValueCodec<
54
+ V extends ValueType,
55
+ RuntimeValue extends RuntimeInputValue,
56
+ RuntimeInputValue = RuntimeValue,
57
+ > {
58
+ protected readonly defaultRuntimeValueStateFactory: RuntimeValueStateFactory<
59
+ RuntimeValue,
60
+ RuntimeInputValue
61
+ > = (encodeValue, decodeValue) => {
62
+ return (instanceState) => {
63
+ const [getInstanceValue, setInstanceValue] = instanceState;
64
+
65
+ const getValue = (): RuntimeValue => {
66
+ return decodeValue(getInstanceValue());
67
+ };
68
+
69
+ const setValue = (runtimeValue: RuntimeInputValue): RuntimeValue => {
70
+ const encodedValue = encodeValue(runtimeValue);
71
+ const persistedValue = setInstanceValue(encodedValue);
72
+
73
+ return decodeValue(persistedValue);
74
+ };
75
+
76
+ return [getValue, setValue];
77
+ };
78
+ };
79
+
80
+ protected readonly defaultDecodeInstanceValueFactory: DecodeInstanceValueFactory<
81
+ RuntimeValue,
82
+ RuntimeInputValue
83
+ > = (encodeValue, decodeValue) => {
84
+ return (instanceValue) => {
85
+ return encodeValue(decodeValue(instanceValue));
86
+ };
87
+ };
88
+
89
+ readonly decodeInstanceValue: DecodeInstanceValue;
90
+ readonly createRuntimeValueState: CreateRuntimeValueState<RuntimeValue, RuntimeInputValue>;
91
+
92
+ constructor(
93
+ readonly valueType: V,
94
+ readonly encodeValue: CodecEncoder<RuntimeInputValue>,
95
+ readonly decodeValue: CodecDecoder<RuntimeValue>,
96
+ options: ValueCodecOptions<RuntimeValue, RuntimeInputValue> = {}
97
+ ) {
98
+ const {
99
+ decodeInstanceValueFactory = this.defaultDecodeInstanceValueFactory,
100
+ runtimeValueStateFactory = this.defaultRuntimeValueStateFactory,
101
+ } = options;
102
+
103
+ this.decodeInstanceValue = decodeInstanceValueFactory(encodeValue, decodeValue);
104
+ this.createRuntimeValueState = runtimeValueStateFactory(encodeValue, decodeValue);
105
+ }
106
+ }
@@ -0,0 +1,19 @@
1
+ import { identity } from '@getodk/common/lib/identity.ts';
2
+ import type { ValueType } from '../../client/ValueType.ts';
3
+ import { ValueCodec } from './ValueCodec.ts';
4
+
5
+ /**
6
+ * Provides fallback functionality where a {@link ValueCodec} is expected, for
7
+ * those {@link ValueType | value types} which are still pending implementation.
8
+ * This allows consistent use of the {@link ValueCodec} interface while
9
+ * maintaining the current behavior of treating those unimplemented value types
10
+ * as string values.
11
+ */
12
+ export class ValueTypePlaceholderCodec<V extends ValueType> extends ValueCodec<V, string, string> {
13
+ constructor(valueType: V) {
14
+ super(valueType, identity, identity, {
15
+ decodeInstanceValueFactory: () => identity,
16
+ runtimeValueStateFactory: () => identity,
17
+ });
18
+ }
19
+ }
@@ -0,0 +1,77 @@
1
+ import type { ValueType } from '../../client/ValueType.ts';
2
+ import {
3
+ DecimalValueCodec,
4
+ type DecimalInputValue,
5
+ type DecimalRuntimeValue,
6
+ } from './DecimalValueCodec.ts';
7
+ import { IntValueCodec, type IntInputValue, type IntRuntimeValue } from './IntValueCodec.ts';
8
+ import { StringValueCodec } from './StringValueCodec.ts';
9
+ import type { ValueCodec } from './ValueCodec.ts';
10
+ import { ValueTypePlaceholderCodec } from './ValueTypePlaceholderCodec.ts';
11
+
12
+ interface RuntimeValuesByType {
13
+ readonly string: string;
14
+ readonly int: IntRuntimeValue;
15
+ readonly decimal: DecimalRuntimeValue;
16
+ readonly boolean: string;
17
+ readonly date: string;
18
+ readonly time: string;
19
+ readonly dateTime: string;
20
+ readonly geopoint: string;
21
+ readonly geotrace: string;
22
+ readonly geoshape: string;
23
+ readonly binary: string;
24
+ readonly barcode: string;
25
+ readonly intent: string;
26
+ }
27
+
28
+ export type RuntimeValue<V extends ValueType> = RuntimeValuesByType[V];
29
+
30
+ interface RuntimeInputValuesByType {
31
+ readonly string: string;
32
+ readonly int: IntInputValue;
33
+ readonly decimal: DecimalInputValue;
34
+ readonly boolean: string;
35
+ readonly date: string;
36
+ readonly time: string;
37
+ readonly dateTime: string;
38
+ readonly geopoint: string;
39
+ readonly geotrace: string;
40
+ readonly geoshape: string;
41
+ readonly binary: string;
42
+ readonly barcode: string;
43
+ readonly intent: string;
44
+ }
45
+
46
+ export type RuntimeInputValue<V extends ValueType> = RuntimeInputValuesByType[V];
47
+
48
+ type SharedValueCodecs = {
49
+ readonly [V in ValueType]: ValueCodec<V, RuntimeValue<V>, RuntimeInputValue<V>>;
50
+ };
51
+
52
+ export type SharedValueCodec<V extends ValueType> = SharedValueCodecs[V];
53
+
54
+ /**
55
+ * Provides codecs for each {@link ValueType | value type}, for nodes with a
56
+ * common representation of those value types.
57
+ */
58
+ export const sharedValueCodecs: SharedValueCodecs = {
59
+ string: new StringValueCodec(),
60
+
61
+ int: new IntValueCodec(),
62
+ decimal: new DecimalValueCodec(),
63
+ boolean: new ValueTypePlaceholderCodec('boolean'),
64
+ date: new ValueTypePlaceholderCodec('date'),
65
+ time: new ValueTypePlaceholderCodec('time'),
66
+ dateTime: new ValueTypePlaceholderCodec('dateTime'),
67
+ geopoint: new ValueTypePlaceholderCodec('geopoint'),
68
+ geotrace: new ValueTypePlaceholderCodec('geotrace'),
69
+ geoshape: new ValueTypePlaceholderCodec('geoshape'),
70
+ binary: new ValueTypePlaceholderCodec('binary'),
71
+ barcode: new ValueTypePlaceholderCodec('barcode'),
72
+ intent: new ValueTypePlaceholderCodec('intent'),
73
+ };
74
+
75
+ export const getSharedValueCodec = <V extends ValueType>(valueType: V): SharedValueCodec<V> => {
76
+ return sharedValueCodecs[valueType];
77
+ };
@@ -15,6 +15,7 @@ const repeatGroupLabelLookup = new ScopedElementLookup(
15
15
  );
16
16
  const repeatLookup = new ScopedElementLookup(':scope > repeat[nodeset]', 'repeat[nodeset]');
17
17
  const valueLookup = new ScopedElementLookup(':scope > value', 'value');
18
+ const submissionLookup = new ScopedElementLookup(':scope > submission', 'submission');
18
19
 
19
20
  export interface HintElement extends LocalNamedElement<'hint'> {}
20
21
 
@@ -60,3 +61,9 @@ export const getRepeatElement = (parent: Element): RepeatElement | null => {
60
61
  export const getValueElement = (parent: ItemElement | ItemsetElement): ValueElement | null => {
61
62
  return valueLookup.getElement<ValueElement>(parent);
62
63
  };
64
+
65
+ export interface SubmissionElement extends LocalNamedElement<'submission'> {}
66
+
67
+ export const getSubmissionElement = (parent: Element): SubmissionElement | null => {
68
+ return submissionLookup.getElement<SubmissionElement>(parent);
69
+ };
@@ -1,8 +1,8 @@
1
1
  import type { Accessor, Setter, Signal } from 'solid-js';
2
2
  import { createSignal } from 'solid-js';
3
+ import type { FormNodeID } from '../../client/identity.ts';
3
4
  import type { OpaqueReactiveObjectFactory } from '../../index.ts';
4
5
  import type { AnyChildNode, AnyParentNode } from '../../instance/hierarchy.ts';
5
- import type { NodeID } from '../../instance/identity.ts';
6
6
  import type { materializeCurrentStateChildren } from './materializeCurrentStateChildren.ts';
7
7
  import type { ClientState } from './node-state/createClientState.ts';
8
8
  import type { CurrentState } from './node-state/createCurrentState.ts';
@@ -12,14 +12,15 @@ export interface ChildrenState<Child extends AnyChildNode> {
12
12
  readonly children: Signal<readonly Child[]>;
13
13
  readonly getChildren: Accessor<readonly Child[]>;
14
14
  readonly setChildren: Setter<readonly Child[]>;
15
- readonly childIds: Accessor<readonly NodeID[]>;
15
+ readonly childIds: Accessor<readonly FormNodeID[]>;
16
16
  }
17
17
 
18
18
  /**
19
19
  * Creates a synchronized pair of:
20
20
  *
21
21
  * - Internal children state suitable for all parent node types
22
- * - The same children state computed as an array of each child's {@link NodeID}
22
+ * - The same children state computed as an array of each child's
23
+ * {@link FormNodeID}
23
24
  *
24
25
  * This state is used, in tandem with {@link materializeCurrentStateChildren},
25
26
  * to ensure children in **client-facing** state are not written into nested
@@ -34,11 +35,12 @@ export interface ChildrenState<Child extends AnyChildNode> {
34
35
  * The produced {@link ChildrenState.childIds} memo is intended to be used to
35
36
  * specify each parent node's `children` in an instance of {@link EngineState}.
36
37
  * In so doing, the node's corresponding (internal, synchronized)
37
- * {@link ClientState} will likewise store only the children's {@link NodeID}s.
38
+ * {@link ClientState} will likewise store only the children's
39
+ * {@link FormNodeID}s.
38
40
  *
39
41
  * As a client reacts to changes in a given parent node's `children` state, that
40
42
  * node's {@link CurrentState} should produce the child nodes corresponding to
41
- * those {@link NodeID}s with the aforementioned
43
+ * those {@link FormNodeID}s with the aforementioned
42
44
  * {@link materializeCurrentStateChildren}.
43
45
  */
44
46
  export const createChildrenState = <Parent extends AnyParentNode, Child extends AnyChildNode>(
@@ -65,7 +67,7 @@ export const createChildrenState = <Parent extends AnyParentNode, Child extends
65
67
  * likely also slightly more efficient. We can revisit the tradeoff if/when
66
68
  * those hypothetical generalizations become a priority.
67
69
  */
68
- const ids = createSignal<readonly NodeID[]>([]);
70
+ const ids = createSignal<readonly FormNodeID[]>([]);
69
71
  const [childIds, setChildIds] = ids;
70
72
 
71
73
  type ChildrenSetterCallback = (prev: readonly Child[]) => readonly Child[];
@@ -1,9 +1,9 @@
1
1
  import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.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 { EvaluationContext } from '../../instance/internal-api/EvaluationContext.ts';
6
- import type { SubscribableDependency } from '../../instance/internal-api/SubscribableDependency.ts';
5
+ import type { EngineXPathNode } from '../../integration/xpath/adapter/kind.ts';
6
+ import type { EngineXPathEvaluator } from '../../integration/xpath/EngineXPathEvaluator.ts';
7
7
  import type {
8
8
  DependentExpression,
9
9
  DependentExpressionResultType,
@@ -12,7 +12,7 @@ import { isConstantExpression } from '../../parse/xpath/semantic-analysis.ts';
12
12
 
13
13
  interface ComputedExpressionResults {
14
14
  readonly boolean: boolean;
15
- readonly nodes: Node[];
15
+ readonly nodes: EngineXPathNode[];
16
16
  readonly number: number;
17
17
  readonly string: string;
18
18
  }
@@ -25,16 +25,18 @@ type EvaluatedExpression<
25
25
  // prettier-ignore
26
26
  type ExpressionEvaluator<
27
27
  Type extends DependentExpressionResultType
28
- > = () => EvaluatedExpression<Type>
28
+ > = () => EvaluatedExpression<Type>;
29
+
30
+ interface ExpressionEvaluatorOptions {
31
+ get contextNode(): EngineXPathNode;
32
+ }
29
33
 
30
34
  const expressionEvaluator = <Type extends DependentExpressionResultType>(
31
- evaluator: XFormsXPathEvaluator,
32
- contextNode: Node,
35
+ evaluator: EngineXPathEvaluator,
33
36
  type: Type,
34
- expression: string
37
+ expression: string,
38
+ options: ExpressionEvaluatorOptions
35
39
  ): ExpressionEvaluator<Type> => {
36
- const options = { contextNode };
37
-
38
40
  switch (type) {
39
41
  case 'boolean':
40
42
  return (() => {
@@ -61,50 +63,71 @@ const expressionEvaluator = <Type extends DependentExpressionResultType>(
61
63
  }
62
64
  };
63
65
 
66
+ type DefaultEvaluationsByType = {
67
+ readonly [Type in DependentExpressionResultType]: EvaluatedExpression<Type>;
68
+ };
69
+
70
+ const DEFAULT_BOOLEAN_EVALUATION = false;
71
+ const DEFAULT_NODES_EVALUATION: [] = [];
72
+ const DEFAULT_NUMBER_EVALUATION = NaN;
73
+ const DEFAULT_STRING_EVALUATION = '';
74
+
75
+ const defaultEvaluationsByType: DefaultEvaluationsByType = {
76
+ boolean: DEFAULT_BOOLEAN_EVALUATION,
77
+ nodes: DEFAULT_NODES_EVALUATION,
78
+ number: DEFAULT_NUMBER_EVALUATION,
79
+ string: DEFAULT_STRING_EVALUATION,
80
+ };
81
+
64
82
  // prettier-ignore
65
83
  type ComputedExpression<Type extends DependentExpressionResultType> = Accessor<
66
84
  EvaluatedExpression<Type>
67
85
  >;
68
86
 
69
- interface CreateComputedExpressionOptions {
70
- readonly arbitraryDependencies?: readonly SubscribableDependency[];
87
+ interface CreateComputedExpressionOptions<Type extends DependentExpressionResultType> {
88
+ /**
89
+ * If a default value is provided, {@link createComputedExpression} will
90
+ * produce this value for computations in a non-attached evaluation context,
91
+ * i.e. when evaluating an expression against a node which has not yet been
92
+ * appended to its parents children state (or which has since been removed
93
+ * from that state). A non-attached state is detected when
94
+ * {@link EvaluationContext.isAttached} returns false.
95
+ *
96
+ * If no default value is provided, an implicit default value is produced as
97
+ * appropriate for the expression's intrinsic result type.
98
+ *
99
+ * @see {@link defaultEvaluationsByType} for these implicit defaults.
100
+ */
101
+ readonly defaultValue?: EvaluatedExpression<Type>;
71
102
  }
72
103
 
73
104
  export const createComputedExpression = <Type extends DependentExpressionResultType>(
74
105
  context: EvaluationContext,
75
106
  dependentExpression: DependentExpression<Type>,
76
- options: CreateComputedExpressionOptions = {}
107
+ options: CreateComputedExpressionOptions<Type> = {}
77
108
  ): ComputedExpression<Type> => {
78
- const { contextNode, evaluator, root, scope } = context;
79
- const { expression, isTranslated, resultType } = dependentExpression;
80
- const dependencyReferences = Array.from(dependentExpression.dependencyReferences);
81
- const evaluateExpression = expressionEvaluator(evaluator, contextNode, resultType, expression);
109
+ return context.scope.runTask(() => {
110
+ const { contextNode, evaluator } = context;
111
+ const { expression, isTranslated, resultType } = dependentExpression;
112
+ const evaluatePreInitializationDefaultValue = () => {
113
+ return options?.defaultValue ?? defaultEvaluationsByType[resultType];
114
+ };
115
+ const evaluateExpression = expressionEvaluator(evaluator, resultType, expression, {
116
+ contextNode,
117
+ });
82
118
 
83
- return scope.runTask(() => {
84
119
  if (isConstantExpression(expression)) {
85
120
  return createMemo(evaluateExpression);
86
121
  }
87
122
 
88
- const { arbitraryDependencies = [] } = options;
89
-
90
- const getReferencedDependencies = createMemo(() => {
91
- return dependencyReferences.flatMap((reference) => {
92
- return context.getSubscribableDependenciesByReference(reference) ?? [];
93
- });
94
- });
95
-
96
123
  return createMemo(() => {
97
- if (isTranslated) {
98
- root.subscribe();
124
+ if (!context.isAttached()) {
125
+ return evaluatePreInitializationDefaultValue();
99
126
  }
100
127
 
101
- arbitraryDependencies.forEach((dependency) => {
102
- dependency.subscribe();
103
- });
104
-
105
- getReferencedDependencies().forEach((dependency) => {
106
- dependency.subscribe();
107
- });
128
+ if (isTranslated) {
129
+ context.getActiveLanguage();
130
+ }
108
131
 
109
132
  return evaluateExpression();
110
133
  });
@@ -0,0 +1,166 @@
1
+ import type { Signal } from 'solid-js';
2
+ import { createComputed, createMemo, createSignal, untrack } from 'solid-js';
3
+ import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
4
+ import type { InstanceValueContext } from '../../instance/internal-api/InstanceValueContext.ts';
5
+ import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
6
+ import { createComputedExpression } from './createComputedExpression.ts';
7
+ import type { SimpleAtomicState, SimpleAtomicStateSetter } from './types.ts';
8
+
9
+ type InitialValueSource = 'FORM_DEFAULT' | 'PRIMARY_INSTANCE';
10
+
11
+ export interface InstanceValueStateOptions {
12
+ /**
13
+ * Specifies the source of a {@link createInstanceValueState} signal's initial
14
+ * value state, where:
15
+ *
16
+ * - 'FORM_DEFAULT': Derives the initial state from the form's definition of
17
+ * the node itself. This is the default option, appropriate when
18
+ * initializing a form without additional primary instance data. In other
19
+ * words, this value should not be used for edits.
20
+ *
21
+ * - 'PRIMARY_INSTANCE': Derives the initial state from the current text
22
+ * content of the {@link ValueNode.contextNode}. This option should be
23
+ * specified when initializing a form with existing primary instance data,
24
+ * such as when editing a previous submission.
25
+ *
26
+ * @default 'FORM_DEFAULT'
27
+ *
28
+ * Specifies whether a {@link createInstanceValueState} signal's initial state
29
+ * should be derived from the current text content of the
30
+ * {@link ValueNode.contextNode | primary instance DOM state}.
31
+ */
32
+ readonly initialValueSource?: InitialValueSource;
33
+ }
34
+
35
+ const getInitialValue = (
36
+ context: InstanceValueContext,
37
+ options: InstanceValueStateOptions
38
+ ): string => {
39
+ const { initialValueSource = 'FORM_DEFAULT' } = options;
40
+
41
+ if (initialValueSource === 'FORM_DEFAULT') {
42
+ const { defaultValue } = context.definition;
43
+
44
+ return context.decodeInstanceValue(defaultValue);
45
+ }
46
+
47
+ throw new ErrorProductionDesignPendingError('Edit implementation pending');
48
+ };
49
+
50
+ type BaseValueState = Signal<string>;
51
+
52
+ type RelevantValueState = SimpleAtomicState<string>;
53
+
54
+ /**
55
+ * Wraps {@link baseValueState} in a signal-like interface which:
56
+ *
57
+ * - produces a blank value for nodes ({@link context}) in a non-relevant state
58
+ * - persists, and restores, the most recent non-blank value state when a
59
+ * node/context's relevance is restored
60
+ */
61
+ const createRelevantValueState = (
62
+ context: InstanceValueContext,
63
+ baseValueState: BaseValueState
64
+ ): RelevantValueState => {
65
+ return context.scope.runTask(() => {
66
+ const [getRelevantValue, setValue] = baseValueState;
67
+
68
+ const getValue = createMemo(() => {
69
+ if (context.isRelevant()) {
70
+ return getRelevantValue();
71
+ }
72
+
73
+ return '';
74
+ });
75
+
76
+ return [getValue, setValue];
77
+ });
78
+ };
79
+
80
+ /**
81
+ * For fields with a `readonly` bind expression, prevent downstream
82
+ * (client/user) writes when the field is in a `readonly` state.
83
+ */
84
+ const guardDownstreamReadonlyWrites = (
85
+ context: InstanceValueContext,
86
+ baseState: SimpleAtomicState<string>
87
+ ): SimpleAtomicState<string> => {
88
+ const { readonly } = context.definition.bind;
89
+
90
+ if (readonly.isDefaultExpression) {
91
+ return baseState;
92
+ }
93
+
94
+ const [getValue, baseSetValue] = baseState;
95
+
96
+ const setValue: SimpleAtomicStateSetter<string> = (value) => {
97
+ if (context.isReadonly()) {
98
+ const reference = untrack(() => context.contextReference());
99
+
100
+ throw new Error(`Cannot write to readonly field: ${reference}`);
101
+ }
102
+
103
+ return baseSetValue(value);
104
+ };
105
+
106
+ return [getValue, setValue];
107
+ };
108
+
109
+ /**
110
+ * Defines a reactive effect which writes the result of `calculate` bind
111
+ * computations to the provided value setter, on initialization and any
112
+ * subsequent reactive update.
113
+ */
114
+ const createCalculation = (
115
+ context: InstanceValueContext,
116
+ setRelevantValue: SimpleAtomicStateSetter<string>,
117
+ calculateDefinition: BindComputationExpression<'calculate'>
118
+ ): void => {
119
+ context.scope.runTask(() => {
120
+ const calculate = createComputedExpression(context, calculateDefinition, {
121
+ defaultValue: '',
122
+ });
123
+
124
+ createComputed(() => {
125
+ if (context.isAttached() && context.isRelevant()) {
126
+ const calculated = calculate();
127
+ const value = context.decodeInstanceValue(calculated);
128
+
129
+ setRelevantValue(value);
130
+ }
131
+ });
132
+ });
133
+ };
134
+
135
+ export type InstanceValueState = SimpleAtomicState<string>;
136
+
137
+ /**
138
+ * Provides a consistent interface for value nodes of any type which:
139
+ *
140
+ * - derives initial state from either an existing instance (e.g. for edits) or
141
+ * the node's definition (e.g. initializing a new submission)
142
+ * - decodes current primary instance state into the value node's runtime type
143
+ * - encodes updated runtime values to store updated instance state
144
+ * - initializes reactive computation of `calculate` bind expressions for those
145
+ * nodes defined with one
146
+ * - prevents downstream writes to nodes in a readonly state
147
+ */
148
+ export const createInstanceValueState = (
149
+ context: InstanceValueContext,
150
+ options: InstanceValueStateOptions = {}
151
+ ): InstanceValueState => {
152
+ return context.scope.runTask(() => {
153
+ const initialValue = getInitialValue(context, options);
154
+ const baseValueState = createSignal(initialValue);
155
+ const relevantValueState = createRelevantValueState(context, baseValueState);
156
+ const { calculate } = context.definition.bind;
157
+
158
+ if (calculate != null) {
159
+ const [, setValue] = relevantValueState;
160
+
161
+ createCalculation(context, setValue, calculate);
162
+ }
163
+
164
+ return guardDownstreamReadonlyWrites(context, relevantValueState);
165
+ });
166
+ };
@@ -1,31 +1,36 @@
1
1
  import type { Accessor } from 'solid-js';
2
2
  import type { EvaluationContext } from '../../instance/internal-api/EvaluationContext.ts';
3
- import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
3
+ import type { NoteNodeDefinition } from '../../parse/model/NoteNodeDefinition.ts';
4
+ import { resolveDependencyNodesets } from '../../parse/xpath/dependency-analysis.ts';
4
5
  import { createComputedExpression } from './createComputedExpression.ts';
5
6
 
6
7
  export const createNoteReadonlyThunk = (
7
8
  context: EvaluationContext,
8
- readonlyDefinition: BindComputationExpression<'readonly'>
9
+ definition: NoteNodeDefinition
9
10
  ): Accessor<true> => {
10
- if (!readonlyDefinition.isConstantTruthyExpression()) {
11
+ const { reference } = definition.bodyElement;
12
+ const { readonly } = definition.bind;
13
+
14
+ if (!readonly.isConstantTruthyExpression()) {
11
15
  throw new Error('Expected a static readonly expression');
12
16
  }
13
17
 
14
18
  let result = true;
15
19
 
16
20
  if (import.meta.env.DEV) {
17
- const { expression } = readonlyDefinition;
21
+ const { expression } = readonly;
22
+ const dependencyReferences = resolveDependencyNodesets(reference, expression);
18
23
 
19
- if (readonlyDefinition.dependencyReferences.size > 0) {
24
+ if (dependencyReferences.length > 0) {
20
25
  throw new Error(`Expected expression ${expression} to have no dependencies`);
21
26
  }
22
27
 
23
- const computedExpression = createComputedExpression(context, readonlyDefinition);
28
+ const computedExpression = createComputedExpression(context, readonly);
24
29
 
25
30
  result = computedExpression();
26
31
 
27
32
  if (result !== true) {
28
- throw new Error(`Expected expression ${readonlyDefinition.expression} to return true`);
33
+ throw new Error(`Expected expression ${readonly.expression} to return true`);
29
34
  }
30
35
  }
31
36