@getodk/xforms-engine 0.1.1 → 0.3.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 (228) hide show
  1. package/dist/body/BodyDefinition.d.ts +24 -7
  2. package/dist/body/BodyElementDefinition.d.ts +4 -3
  3. package/dist/body/RepeatElementDefinition.d.ts +19 -0
  4. package/dist/body/appearance/inputAppearanceParser.d.ts +4 -0
  5. package/dist/body/appearance/selectAppearanceParser.d.ts +4 -0
  6. package/dist/body/appearance/structureElementAppearanceParser.d.ts +4 -0
  7. package/dist/body/control/ControlDefinition.d.ts +4 -2
  8. package/dist/body/control/InputDefinition.d.ts +5 -0
  9. package/dist/body/control/select/ItemDefinition.d.ts +2 -2
  10. package/dist/body/control/select/ItemsetDefinition.d.ts +5 -4
  11. package/dist/body/control/select/SelectDefinition.d.ts +11 -1
  12. package/dist/body/group/BaseGroupDefinition.d.ts +4 -9
  13. package/dist/body/group/PresentationGroupDefinition.d.ts +1 -1
  14. package/dist/client/BaseNode.d.ts +74 -3
  15. package/dist/client/GroupNode.d.ts +7 -2
  16. package/dist/client/ModelValueNode.d.ts +37 -0
  17. package/dist/client/NodeAppearances.d.ts +15 -0
  18. package/dist/client/NoteNode.d.ts +53 -0
  19. package/dist/client/RootNode.d.ts +21 -0
  20. package/dist/client/SelectNode.d.ts +8 -3
  21. package/dist/client/StringNode.d.ts +8 -3
  22. package/dist/client/SubtreeNode.d.ts +3 -0
  23. package/dist/client/TextRange.d.ts +85 -2
  24. package/dist/client/constants.d.ts +9 -0
  25. package/dist/client/hierarchy.d.ts +14 -9
  26. package/dist/client/node-types.d.ts +2 -1
  27. package/dist/client/{RepeatRangeNode.d.ts → repeat/BaseRepeatRangeNode.d.ts} +19 -15
  28. package/dist/client/{RepeatInstanceNode.d.ts → repeat/RepeatInstanceNode.d.ts} +11 -7
  29. package/dist/client/repeat/RepeatRangeControlledNode.d.ts +19 -0
  30. package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +20 -0
  31. package/dist/client/validation.d.ts +163 -0
  32. package/dist/expression/DependentExpression.d.ts +12 -8
  33. package/dist/index.d.ts +9 -4
  34. package/dist/index.js +3173 -960
  35. package/dist/index.js.map +1 -1
  36. package/dist/instance/Group.d.ts +6 -4
  37. package/dist/instance/ModelValue.d.ts +40 -0
  38. package/dist/instance/Note.d.ts +42 -0
  39. package/dist/instance/Root.d.ts +10 -23
  40. package/dist/instance/SelectField.d.ts +12 -6
  41. package/dist/instance/StringField.d.ts +13 -7
  42. package/dist/instance/Subtree.d.ts +3 -1
  43. package/dist/instance/abstract/DescendantNode.d.ts +16 -9
  44. package/dist/instance/abstract/InstanceNode.d.ts +28 -29
  45. package/dist/instance/hierarchy.d.ts +10 -5
  46. package/dist/instance/internal-api/EvaluationContext.d.ts +5 -4
  47. package/dist/instance/internal-api/ValidationContext.d.ts +21 -0
  48. package/dist/instance/internal-api/ValueContext.d.ts +2 -2
  49. package/dist/instance/repeat/BaseRepeatRange.d.ts +160 -0
  50. package/dist/instance/{RepeatInstance.d.ts → repeat/RepeatInstance.d.ts} +38 -13
  51. package/dist/instance/repeat/RepeatRangeControlled.d.ts +16 -0
  52. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +35 -0
  53. package/dist/instance/text/TextRange.d.ts +4 -4
  54. package/dist/lib/TokenListParser.d.ts +84 -0
  55. package/dist/lib/dom/query.d.ts +5 -0
  56. package/dist/lib/reactivity/createComputedExpression.d.ts +6 -1
  57. package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +5 -0
  58. package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +2 -1
  59. package/dist/lib/reactivity/node-state/createSharedNodeState.d.ts +1 -1
  60. package/dist/lib/reactivity/node-state/createSpecifiedState.d.ts +1 -1
  61. package/dist/lib/reactivity/text/createFieldHint.d.ts +3 -3
  62. package/dist/lib/reactivity/text/createNodeLabel.d.ts +2 -2
  63. package/dist/lib/reactivity/text/createNoteText.d.ts +25 -0
  64. package/dist/lib/reactivity/text/createTextRange.d.ts +5 -7
  65. package/dist/lib/reactivity/validation/createAggregatedViolations.d.ts +9 -0
  66. package/dist/lib/reactivity/validation/createValidation.d.ts +18 -0
  67. package/dist/model/BindDefinition.d.ts +4 -2
  68. package/dist/model/BindElement.d.ts +1 -0
  69. package/dist/model/DescendentNodeDefinition.d.ts +1 -2
  70. package/dist/model/{ValueNodeDefinition.d.ts → LeafNodeDefinition.d.ts} +3 -4
  71. package/dist/model/NodeDefinition.d.ts +16 -16
  72. package/dist/model/RepeatInstanceDefinition.d.ts +5 -6
  73. package/dist/model/RepeatRangeDefinition.d.ts +30 -0
  74. package/dist/model/RepeatTemplateDefinition.d.ts +6 -7
  75. package/dist/model/RootDefinition.d.ts +3 -1
  76. package/dist/model/SubtreeDefinition.d.ts +2 -2
  77. package/dist/parse/NoteNodeDefinition.d.ts +31 -0
  78. package/dist/parse/expression/RepeatCountControlExpression.d.ts +19 -0
  79. package/dist/parse/text/HintDefinition.d.ts +9 -0
  80. package/dist/parse/text/ItemLabelDefinition.d.ts +9 -0
  81. package/dist/parse/text/ItemsetLabelDefinition.d.ts +13 -0
  82. package/dist/parse/text/LabelDefinition.d.ts +15 -0
  83. package/dist/parse/text/MessageDefinition.d.ts +15 -0
  84. package/dist/parse/text/OutputChunkDefinition.d.ts +8 -0
  85. package/dist/parse/text/ReferenceChunkDefinition.d.ts +8 -0
  86. package/dist/parse/text/StaticTextChunkDefinition.d.ts +10 -0
  87. package/dist/parse/text/TranslationChunkDefinition.d.ts +9 -0
  88. package/dist/parse/text/abstract/TextChunkDefinition.d.ts +18 -0
  89. package/dist/parse/text/abstract/TextElementDefinition.d.ts +23 -0
  90. package/dist/parse/text/abstract/TextRangeDefinition.d.ts +35 -0
  91. package/dist/parse/xpath/dependency-analysis.d.ts +40 -0
  92. package/dist/parse/xpath/path-resolution.d.ts +70 -0
  93. package/dist/parse/xpath/predicate-analysis.d.ts +30 -0
  94. package/dist/parse/xpath/reference-parsing.d.ts +18 -0
  95. package/dist/parse/xpath/semantic-analysis.d.ts +98 -0
  96. package/dist/parse/xpath/syntax-traversal.d.ts +69 -0
  97. package/dist/solid.js +3174 -961
  98. package/dist/solid.js.map +1 -1
  99. package/package.json +14 -15
  100. package/src/XFormDOM.ts +81 -8
  101. package/src/body/BodyDefinition.ts +38 -23
  102. package/src/body/BodyElementDefinition.ts +4 -3
  103. package/src/body/RepeatElementDefinition.ts +58 -0
  104. package/src/body/appearance/inputAppearanceParser.ts +39 -0
  105. package/src/body/appearance/selectAppearanceParser.ts +38 -0
  106. package/src/body/appearance/structureElementAppearanceParser.ts +7 -0
  107. package/src/body/control/ControlDefinition.ts +8 -3
  108. package/src/body/control/InputDefinition.ts +13 -0
  109. package/src/body/control/select/ItemDefinition.ts +3 -3
  110. package/src/body/control/select/ItemsetDefinition.ts +29 -12
  111. package/src/body/control/select/ItemsetNodesetExpression.ts +1 -1
  112. package/src/body/control/select/SelectDefinition.ts +14 -5
  113. package/src/body/group/BaseGroupDefinition.ts +14 -51
  114. package/src/body/group/PresentationGroupDefinition.ts +1 -1
  115. package/src/client/BaseNode.ts +82 -8
  116. package/src/client/GroupNode.ts +8 -2
  117. package/src/client/ModelValueNode.ts +40 -0
  118. package/src/client/NodeAppearances.ts +22 -0
  119. package/src/client/NoteNode.ts +74 -0
  120. package/src/client/README.md +1 -0
  121. package/src/client/RootNode.ts +24 -0
  122. package/src/client/SelectNode.ts +9 -3
  123. package/src/client/StringNode.ts +9 -3
  124. package/src/client/SubtreeNode.ts +3 -0
  125. package/src/client/TextRange.ts +99 -2
  126. package/src/client/constants.ts +10 -0
  127. package/src/client/hierarchy.ts +30 -14
  128. package/src/client/node-types.ts +8 -1
  129. package/src/client/{RepeatRangeNode.ts → repeat/BaseRepeatRangeNode.ts} +20 -17
  130. package/src/client/{RepeatInstanceNode.ts → repeat/RepeatInstanceNode.ts} +13 -7
  131. package/src/client/repeat/RepeatRangeControlledNode.ts +20 -0
  132. package/src/client/repeat/RepeatRangeUncontrolledNode.ts +21 -0
  133. package/src/client/validation.ts +199 -0
  134. package/src/expression/DependentExpression.ts +45 -27
  135. package/src/index.ts +15 -8
  136. package/src/instance/Group.ts +24 -13
  137. package/src/instance/ModelValue.ts +104 -0
  138. package/src/instance/Note.ts +142 -0
  139. package/src/instance/Root.ts +29 -67
  140. package/src/instance/SelectField.ts +35 -13
  141. package/src/instance/StringField.ts +40 -13
  142. package/src/instance/Subtree.ts +19 -10
  143. package/src/instance/abstract/DescendantNode.ts +50 -49
  144. package/src/instance/abstract/InstanceNode.ts +89 -92
  145. package/src/instance/children.ts +47 -10
  146. package/src/instance/hierarchy.ts +21 -2
  147. package/src/instance/index.ts +1 -1
  148. package/src/instance/internal-api/EvaluationContext.ts +5 -6
  149. package/src/instance/internal-api/ValidationContext.ts +23 -0
  150. package/src/instance/internal-api/ValueContext.ts +2 -2
  151. package/src/instance/repeat/BaseRepeatRange.ts +347 -0
  152. package/src/instance/{RepeatInstance.ts → repeat/RepeatInstance.ts} +85 -36
  153. package/src/instance/repeat/RepeatRangeControlled.ts +82 -0
  154. package/src/instance/repeat/RepeatRangeUncontrolled.ts +67 -0
  155. package/src/instance/text/TextRange.ts +10 -4
  156. package/src/lib/TokenListParser.ts +156 -0
  157. package/src/lib/dom/query.ts +13 -0
  158. package/src/lib/reactivity/createChildrenState.ts +51 -6
  159. package/src/lib/reactivity/createComputedExpression.ts +23 -25
  160. package/src/lib/reactivity/createNoteReadonlyThunk.ts +33 -0
  161. package/src/lib/reactivity/createSelectItems.ts +25 -20
  162. package/src/lib/reactivity/createValueState.ts +6 -6
  163. package/src/lib/reactivity/materializeCurrentStateChildren.ts +3 -1
  164. package/src/lib/reactivity/node-state/createSharedNodeState.ts +1 -1
  165. package/src/lib/reactivity/text/createFieldHint.ts +9 -7
  166. package/src/lib/reactivity/text/createNodeLabel.ts +7 -5
  167. package/src/lib/reactivity/text/createNoteText.ts +72 -0
  168. package/src/lib/reactivity/text/createTextRange.ts +17 -90
  169. package/src/lib/reactivity/validation/createAggregatedViolations.ts +70 -0
  170. package/src/lib/reactivity/validation/createValidation.ts +196 -0
  171. package/src/model/BindComputation.ts +0 -4
  172. package/src/model/BindDefinition.ts +8 -6
  173. package/src/model/BindElement.ts +1 -0
  174. package/src/model/DescendentNodeDefinition.ts +1 -2
  175. package/src/model/{ValueNodeDefinition.ts → LeafNodeDefinition.ts} +5 -6
  176. package/src/model/ModelBindMap.ts +4 -0
  177. package/src/model/ModelDefinition.ts +1 -1
  178. package/src/model/NodeDefinition.ts +21 -21
  179. package/src/model/RepeatInstanceDefinition.ts +8 -13
  180. package/src/model/RepeatRangeDefinition.ts +94 -0
  181. package/src/model/RepeatTemplateDefinition.ts +10 -15
  182. package/src/model/RootDefinition.ts +12 -14
  183. package/src/model/SubtreeDefinition.ts +3 -3
  184. package/src/parse/NoteNodeDefinition.ts +70 -0
  185. package/src/parse/TODO.md +3 -0
  186. package/src/parse/expression/RepeatCountControlExpression.ts +44 -0
  187. package/src/parse/text/HintDefinition.ts +25 -0
  188. package/src/parse/text/ItemLabelDefinition.ts +25 -0
  189. package/src/parse/text/ItemsetLabelDefinition.ts +44 -0
  190. package/src/parse/text/LabelDefinition.ts +61 -0
  191. package/src/parse/text/MessageDefinition.ts +49 -0
  192. package/src/parse/text/OutputChunkDefinition.ts +25 -0
  193. package/src/parse/text/ReferenceChunkDefinition.ts +14 -0
  194. package/src/parse/text/StaticTextChunkDefinition.ts +19 -0
  195. package/src/parse/text/TranslationChunkDefinition.ts +38 -0
  196. package/src/parse/text/abstract/TextChunkDefinition.ts +38 -0
  197. package/src/parse/text/abstract/TextElementDefinition.ts +71 -0
  198. package/src/parse/text/abstract/TextRangeDefinition.ts +70 -0
  199. package/src/parse/xpath/dependency-analysis.ts +105 -0
  200. package/src/parse/xpath/path-resolution.ts +475 -0
  201. package/src/parse/xpath/predicate-analysis.ts +61 -0
  202. package/src/parse/xpath/reference-parsing.ts +90 -0
  203. package/src/parse/xpath/semantic-analysis.ts +466 -0
  204. package/src/parse/xpath/syntax-traversal.ts +129 -0
  205. package/dist/body/RepeatDefinition.d.ts +0 -16
  206. package/dist/body/group/RepeatGroupDefinition.d.ts +0 -13
  207. package/dist/body/text/HintDefinition.d.ts +0 -11
  208. package/dist/body/text/LabelDefinition.d.ts +0 -20
  209. package/dist/body/text/TextElementDefinition.d.ts +0 -33
  210. package/dist/body/text/TextElementOutputPart.d.ts +0 -13
  211. package/dist/body/text/TextElementPart.d.ts +0 -13
  212. package/dist/body/text/TextElementReferencePart.d.ts +0 -7
  213. package/dist/body/text/TextElementStaticPart.d.ts +0 -7
  214. package/dist/instance/RepeatRange.d.ts +0 -80
  215. package/dist/lib/xpath/analysis.d.ts +0 -23
  216. package/dist/model/RepeatSequenceDefinition.d.ts +0 -20
  217. package/src/body/RepeatDefinition.ts +0 -54
  218. package/src/body/group/RepeatGroupDefinition.ts +0 -91
  219. package/src/body/text/HintDefinition.ts +0 -26
  220. package/src/body/text/LabelDefinition.ts +0 -54
  221. package/src/body/text/TextElementDefinition.ts +0 -97
  222. package/src/body/text/TextElementOutputPart.ts +0 -27
  223. package/src/body/text/TextElementPart.ts +0 -31
  224. package/src/body/text/TextElementReferencePart.ts +0 -21
  225. package/src/body/text/TextElementStaticPart.ts +0 -26
  226. package/src/instance/RepeatRange.ts +0 -214
  227. package/src/lib/xpath/analysis.ts +0 -241
  228. package/src/model/RepeatSequenceDefinition.ts +0 -53
@@ -0,0 +1,160 @@
1
+ import { Accessor } from 'solid-js';
2
+ import { NodeAppearances } from '../../client/NodeAppearances.ts';
3
+ import { BaseRepeatRangeNode } from '../../client/repeat/BaseRepeatRangeNode.ts';
4
+ import { TextRange } from '../../client/TextRange.ts';
5
+ import { AncestorNodeValidationState } from '../../client/validation.ts';
6
+ import { ChildrenState } from '../../lib/reactivity/createChildrenState.ts';
7
+ import { MaterializedChildren } from '../../lib/reactivity/materializeCurrentStateChildren.ts';
8
+ import { CurrentState } from '../../lib/reactivity/node-state/createCurrentState.ts';
9
+ import { EngineState } from '../../lib/reactivity/node-state/createEngineState.ts';
10
+ import { SharedNodeState } from '../../lib/reactivity/node-state/createSharedNodeState.ts';
11
+ import { AnyRepeatRangeDefinition, ControlledRepeatRangeDefinition } from '../../model/RepeatRangeDefinition.ts';
12
+ import { DescendantNodeParent, DescendantNodeSharedStateSpec, DescendantNode } from '../abstract/DescendantNode.ts';
13
+ import { NodeID } from '../identity.ts';
14
+ import { EvaluationContext } from '../internal-api/EvaluationContext.ts';
15
+ import { SubscribableDependency } from '../internal-api/SubscribableDependency.ts';
16
+ import { RepeatInstance, RepeatDefinition } from './RepeatInstance.ts';
17
+
18
+ interface RepeatRangeStateSpec extends DescendantNodeSharedStateSpec {
19
+ readonly hint: null;
20
+ readonly label: Accessor<TextRange<'label'> | null>;
21
+ readonly children: Accessor<readonly NodeID[]>;
22
+ readonly valueOptions: null;
23
+ readonly value: null;
24
+ }
25
+ type BaseRepeatRangeNodeType<Definition extends AnyRepeatRangeDefinition> = Definition extends ControlledRepeatRangeDefinition ? 'repeat-range:controlled' : 'repeat-range:uncontrolled';
26
+ export declare abstract class BaseRepeatRange<Definition extends AnyRepeatRangeDefinition> extends DescendantNode<Definition, RepeatRangeStateSpec, RepeatInstance> implements BaseRepeatRangeNode, EvaluationContext, SubscribableDependency {
27
+ /**
28
+ * A repeat range doesn't have a corresponding primary instance element of its
29
+ * own, and its instances are appended to the range's parent element. During
30
+ * creation of the initial primary instance state and DOM trees, we _could_
31
+ * reliably append all of the range's instances in order as the definition
32
+ * tree is recursed. But that would fail to handle some instance addition
33
+ * cases afterwards.
34
+ *
35
+ * Most notably, we need to know where in the primary instance tree to append
36
+ * instances created for a range which is currently empty. As a lucky
37
+ * coincidence, this need coincides with the ability to add instances at any
38
+ * arbitrary index within the range. In each case, we can reference a primary
39
+ * instance DOM node which will become the new instance's preceding sibling.
40
+ * Where the range is empty, we use this {@link Comment} node (itself created
41
+ * and appended during range initialization) in lieu of a nonexistent
42
+ * preceding instance's {@link contextNode}.
43
+ *
44
+ * @todo We likely want to remove these during submission serialization.
45
+ * @todo Can we use a
46
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/Range | DOM Range}
47
+ * instead?
48
+ */
49
+ protected readonly anchorNode: Comment;
50
+ protected readonly childrenState: ChildrenState<RepeatInstance>;
51
+ /**
52
+ * Provides an {@link EvaluationContext} from which to evaluate expressions
53
+ * where some LocationPath sub-expressions may be **relative to the repeat
54
+ * range itself**. This is useful for evaluation of expressions where:
55
+ *
56
+ * - the expression is typically contextualized to any of its
57
+ * {@link RepeatInstance} children, but it presently has none (i.e.
58
+ * `relevant`)
59
+ *
60
+ * - the expression is conceptually intended to be evaluated in the context of
61
+ * the repeat range itself (i.e. `jr:count`)
62
+ */
63
+ protected readonly selfEvaluationContext: EvaluationContext & {
64
+ readonly contextNode: Comment;
65
+ };
66
+ /**
67
+ * @see {@link isSelfRelevant}
68
+ */
69
+ protected readonly isEmptyRangeSelfRelevant: Accessor<boolean>;
70
+ protected readonly state: SharedNodeState<RepeatRangeStateSpec>;
71
+ protected engineState: EngineState<RepeatRangeStateSpec>;
72
+ /**
73
+ * @todo Should we special case repeat `readonly` state the same way
74
+ * we do for `relevant`?
75
+ *
76
+ * @see {@link isSelfRelevant}
77
+ */
78
+ isSelfReadonly: Accessor<boolean>;
79
+ /**
80
+ * A repeat range does not exist in the primary instance tree. A `relevant`
81
+ * expression applies to each {@link RepeatInstance} child of the repeat
82
+ * range. Determining whether a repeat range itself "is relevant" isn't a
83
+ * concept the spec addresses, but it may be used by clients to determine
84
+ * whether to allow interaction with the range (e.g. by adding a repeat
85
+ * instance, or presenting the range's label when empty).
86
+ *
87
+ * As a naive first pass, it seems like the heuristic for this should be:
88
+ *
89
+ * 1. Does the repeat range have any repeat instance children?
90
+ *
91
+ * - If yes, go to 2.
92
+ * - If no, go to 3.
93
+ *
94
+ * 2. Does one or more of those children return `true` for the node's
95
+ * `relevant` expression (i.e. is the repeat instance "self relevant")?
96
+ *
97
+ * 3. Does the relevant expression return `true` for the repeat range itself
98
+ * (where, at least for now, the context of that evaluation would be the
99
+ * repeat range's {@link anchorNode} to ensure correct relative expressions
100
+ * resolve correctly)?
101
+ *
102
+ * @todo While (3) is proactively implemented, there isn't presently a test
103
+ * exercising it. It felt best for now to surface this for discussion in
104
+ * review to validate that it's going in the right direction.
105
+ *
106
+ * @todo While (2) **is actually tested**, the tests currently in place behave
107
+ * the same way with only the logic for (3), regardless of whether the repeat
108
+ * range actually has any repeat instance children. It's unclear (a) if that's
109
+ * a preferable simplification and (b) how that might affect performance (in
110
+ * theory it could vary depending on form structure and runtime state).
111
+ */
112
+ readonly isSelfRelevant: Accessor<boolean>;
113
+ abstract readonly nodeType: BaseRepeatRangeNodeType<Definition>;
114
+ /**
115
+ * @todo RepeatRange*, RepeatInstance* (and RepeatTemplate*) all share the
116
+ * same body element, and thus all share the same definition `bodyElement`. As
117
+ * such, they also all share the same `appearances`. At time of writing,
118
+ * `web-forms` (Vue UI package) treats a `RepeatRangeNode`...
119
+ *
120
+ * - ... as a group, if the node has a label (i.e.
121
+ * `<group><label/><repeat/></group>`)
122
+ * - ... effectively as a fragment containing only its instances, otherwise
123
+ *
124
+ * We now collapse `<group><repeat>` into `<repeat>`, and no longer treat
125
+ * "repeat group" as a concept (after parsing). According to the spec, these
126
+ * appearances **are supposed to** come from that "repeat group" in the form
127
+ * definition. In practice, many forms do define appearances directly on a
128
+ * repeat element. The engine currently produces an error if both are defined
129
+ * simultaneously, but otherwise makes no distinction between appearances in
130
+ * these form definition shapes:
131
+ *
132
+ * ```xml
133
+ * <group ref="/data/rep1" appearance="...">
134
+ * <repeat nodeset="/data/rep1"/>
135
+ * </group>
136
+ *
137
+ * <group ref="/data/rep1">
138
+ * <repeat nodeset="/data/rep1"/ appearance="...">
139
+ * </group>
140
+ *
141
+ * <repeat nodeset="/data/rep1"/ appearance="...">
142
+ * ```
143
+ *
144
+ * All of the above creates considerable ambiguity about where "repeat
145
+ * appearances" should apply, under which circumstances.
146
+ */
147
+ abstract readonly appearances: NodeAppearances<Definition>;
148
+ readonly currentState: MaterializedChildren<CurrentState<RepeatRangeStateSpec>, RepeatInstance>;
149
+ abstract readonly validationState: AncestorNodeValidationState;
150
+ constructor(parent: DescendantNodeParent<Definition>, definition: Definition);
151
+ protected getLastIndex(): number;
152
+ protected initializeContextNode(parentContextNode: Element): Element;
153
+ getInstanceIndex(instance: RepeatInstance): number;
154
+ private createChildren;
155
+ protected addChildren(afterIndex: number, definitions: readonly RepeatDefinition[]): readonly RepeatInstance[];
156
+ protected removeChildren(startIndex: number, count: number): readonly RepeatInstance[];
157
+ subscribe(): void;
158
+ getChildren(): readonly RepeatInstance[];
159
+ }
160
+ export {};
@@ -1,16 +1,16 @@
1
1
  import { Accessor } from 'solid-js';
2
- import { RepeatDefinition, RepeatInstanceNode } from '../client/RepeatInstanceNode.ts';
3
- import { TextRange } from '../index.ts';
4
- import { MaterializedChildren } from '../lib/reactivity/materializeCurrentStateChildren.ts';
5
- import { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
6
- import { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
7
- import { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
8
- import { RepeatRange } from './RepeatRange.ts';
9
- import { DescendantNodeSharedStateSpec, DescendantNode } from './abstract/DescendantNode.ts';
10
- import { AnyChildNode, GeneralChildNode } from './hierarchy.ts';
11
- import { NodeID } from './identity.ts';
12
- import { EvaluationContext } from './internal-api/EvaluationContext.ts';
13
- import { SubscribableDependency } from './internal-api/SubscribableDependency.ts';
2
+ import { RepeatDefinition, RepeatInstanceNode, RepeatInstanceNodeAppearances } from '../../client/repeat/RepeatInstanceNode.ts';
3
+ import { TextRange } from '../../client/TextRange.ts';
4
+ import { AncestorNodeValidationState } from '../../client/validation.ts';
5
+ import { MaterializedChildren } from '../../lib/reactivity/materializeCurrentStateChildren.ts';
6
+ import { CurrentState } from '../../lib/reactivity/node-state/createCurrentState.ts';
7
+ import { EngineState } from '../../lib/reactivity/node-state/createEngineState.ts';
8
+ import { SharedNodeState } from '../../lib/reactivity/node-state/createSharedNodeState.ts';
9
+ import { DescendantNodeSharedStateSpec, DescendantNode } from '../abstract/DescendantNode.ts';
10
+ import { AnyChildNode, GeneralChildNode, RepeatRange } from '../hierarchy.ts';
11
+ import { NodeID } from '../identity.ts';
12
+ import { EvaluationContext } from '../internal-api/EvaluationContext.ts';
13
+ import { SubscribableDependency } from '../internal-api/SubscribableDependency.ts';
14
14
 
15
15
  export type { RepeatDefinition };
16
16
  interface RepeatInstanceStateSpec extends DescendantNodeSharedStateSpec {
@@ -30,10 +30,35 @@ export declare class RepeatInstance extends DescendantNode<RepeatDefinition, Rep
30
30
  private readonly currentIndex;
31
31
  protected readonly state: SharedNodeState<RepeatInstanceStateSpec>;
32
32
  protected engineState: EngineState<RepeatInstanceStateSpec>;
33
+ /**
34
+ * @todo Should we special case repeat `readonly` inheritance the same way
35
+ * we do for `relevant`?
36
+ *
37
+ * @see {@link hasNonRelevantAncestor}
38
+ */
39
+ readonly hasReadonlyAncestor: Accessor<boolean>;
40
+ /**
41
+ * A repeat instance can inherit non-relevance, just like any other node. That
42
+ * inheritance is derived from the repeat instance's parent node in the
43
+ * primary instance XML/DOM tree (and would be semantically expected to do so
44
+ * even if we move away from that implementation detail).
45
+ *
46
+ * Since {@link RepeatInstance.parent} is a {@link RepeatRange}, which is a
47
+ * runtime data model fiction that does not exist in that hierarchy, we pass
48
+ * this call through, allowing the {@link RepeatRange} to check the actual
49
+ * primary instance parent node's relevance state.
50
+ *
51
+ * @todo Should we apply similar reasoning in {@link hasReadonlyAncestor}?
52
+ */
53
+ readonly hasNonRelevantAncestor: Accessor<boolean>;
33
54
  readonly nodeType = "repeat-instance";
55
+ /**
56
+ * @see {@link RepeatRange.appearances}
57
+ */
58
+ readonly appearances: RepeatInstanceNodeAppearances;
34
59
  readonly currentState: MaterializedChildren<CurrentState<RepeatInstanceStateSpec>, GeneralChildNode>;
60
+ readonly validationState: AncestorNodeValidationState;
35
61
  constructor(parent: RepeatRange, definition: RepeatDefinition, options: RepeatInstanceOptions);
36
- protected computeReference(parent: RepeatRange): string;
37
62
  protected initializeContextNode(parentContextNode: Element, nodeName: string): Element;
38
63
  subscribe(): void;
39
64
  getChildren(): readonly GeneralChildNode[];
@@ -0,0 +1,16 @@
1
+ import { RepeatRangeNodeAppearances } from '../../client/repeat/BaseRepeatRangeNode.ts';
2
+ import { RepeatRangeControlledNode } from '../../client/repeat/RepeatRangeControlledNode.ts';
3
+ import { AncestorNodeValidationState } from '../../client/validation.ts';
4
+ import { ControlledRepeatRangeDefinition } from '../../model/RepeatRangeDefinition.ts';
5
+ import { GeneralParentNode } from '../hierarchy.ts';
6
+ import { EvaluationContext } from '../internal-api/EvaluationContext.ts';
7
+ import { SubscribableDependency } from '../internal-api/SubscribableDependency.ts';
8
+ import { BaseRepeatRange } from './BaseRepeatRange.ts';
9
+
10
+ export declare class RepeatRangeControlled extends BaseRepeatRange<ControlledRepeatRangeDefinition> implements RepeatRangeControlledNode, EvaluationContext, SubscribableDependency {
11
+ readonly nodeType = "repeat-range:controlled";
12
+ readonly appearances: RepeatRangeNodeAppearances;
13
+ readonly validationState: AncestorNodeValidationState;
14
+ constructor(parent: GeneralParentNode, definition: ControlledRepeatRangeDefinition);
15
+ private initializeControlledChildrenState;
16
+ }
@@ -0,0 +1,35 @@
1
+ import { RepeatRangeNodeAppearances } from '../../client/repeat/BaseRepeatRangeNode.ts';
2
+ import { RepeatRangeUncontrolledNode } from '../../client/repeat/RepeatRangeUncontrolledNode.ts';
3
+ import { AncestorNodeValidationState } from '../../client/validation.ts';
4
+ import { UncontrolledRepeatRangeDefinition } from '../../model/RepeatRangeDefinition.ts';
5
+ import { GeneralParentNode } from '../hierarchy.ts';
6
+ import { EvaluationContext } from '../internal-api/EvaluationContext.ts';
7
+ import { SubscribableDependency } from '../internal-api/SubscribableDependency.ts';
8
+ import { Root } from '../Root.ts';
9
+ import { BaseRepeatRange } from './BaseRepeatRange.ts';
10
+
11
+ export declare class RepeatRangeUncontrolled extends BaseRepeatRange<UncontrolledRepeatRangeDefinition> implements RepeatRangeUncontrolledNode, EvaluationContext, SubscribableDependency {
12
+ readonly nodeType = "repeat-range:uncontrolled";
13
+ readonly appearances: RepeatRangeNodeAppearances;
14
+ readonly validationState: AncestorNodeValidationState;
15
+ constructor(parent: GeneralParentNode, definition: UncontrolledRepeatRangeDefinition);
16
+ addInstances(afterIndex?: number, count?: number): Root;
17
+ /**
18
+ * Removes the {@link RepeatInstance}s corresponding to the specified range of
19
+ * indexes, and then removes those repeat instances from the repeat range's
20
+ * own children state in that order:
21
+ *
22
+ * 1. Identify the set of {@link RepeatInstance}s to be removed.
23
+ *
24
+ * 2. For each {@link RepeatInstance} pending removal, perform that node's
25
+ * removal logic. @see {@link RepeatInstance.remove} for more detail.
26
+ *
27
+ * 3. Finalize update to the repeat range's own {@link childrenState},
28
+ * omitting those {@link RepeatInstance}s which were removed.
29
+ *
30
+ * This ordering ensures a consistent representation of state is established
31
+ * prior to any downstream reactive updates, and ensures that removed nodes'
32
+ * reactivity is cleaned up.
33
+ */
34
+ removeInstances(startIndex: number, count?: number): Root;
35
+ }
@@ -1,11 +1,11 @@
1
- import { TextRange as ClientTextRange, TextChunk } from '../../client/TextRange.ts';
1
+ import { TextRange as ClientTextRange, TextChunk, TextOrigin, TextRole } from '../../client/TextRange.ts';
2
2
 
3
- export type TextRole = 'hint' | 'label';
4
- export declare class TextRange<Role extends TextRole> implements ClientTextRange<Role> {
3
+ export declare class TextRange<Role extends TextRole, Origin extends TextOrigin> implements ClientTextRange<Role, Origin> {
4
+ readonly origin: Origin;
5
5
  readonly role: Role;
6
6
  protected readonly chunks: readonly TextChunk[];
7
7
  [Symbol.iterator](): Generator<TextChunk, void, undefined>;
8
8
  get formatted(): Record<PropertyKey, unknown>;
9
9
  get asString(): string;
10
- constructor(role: Role, chunks: readonly TextChunk[]);
10
+ constructor(origin: Origin, role: Role, chunks: readonly TextChunk[]);
11
11
  }
@@ -0,0 +1,84 @@
1
+ import { PartiallyKnownString } from '../../../common/types/string/PartiallyKnownString.ts';
2
+
3
+ type SymbolIterator = typeof Symbol.iterator;
4
+ type TokenListKey<CanonicalToken extends string> = PartiallyKnownString<CanonicalToken> | SymbolIterator;
5
+ type TokenListIterator<CanonicalToken extends string> = IterableIterator<PartiallyKnownString<CanonicalToken>>;
6
+ /**
7
+ * @see {@link TokenListParser}
8
+ */
9
+ export type TokenList<CanonicalToken extends string = string> = {
10
+ readonly [Key in TokenListKey<CanonicalToken>]: Key extends SymbolIterator ? () => TokenListIterator<CanonicalToken> : boolean;
11
+ };
12
+ interface TokenListAlias<CanonicalToken extends string> {
13
+ readonly fromAlias: string;
14
+ readonly toCanonical: CanonicalToken;
15
+ }
16
+ type TokenAliases<CanonicalToken extends string> = ReadonlyArray<TokenListAlias<CanonicalToken>>;
17
+ interface TokenListParserOptions<CanonicalToken extends string> {
18
+ readonly aliases?: TokenAliases<CanonicalToken>;
19
+ }
20
+ type TokenListAttributeName = PartiallyKnownString<'appearance' | 'class'>;
21
+ /**
22
+ * Intended primarily for use in parsing these features:
23
+ *
24
+ * - {@link https://getodk.github.io/xforms-spec/#appearances | appearances} ({@link https://xlsform.org/en/#appearance | additional documentation})
25
+ *
26
+ * - {@link https://getodk.github.io/xforms-spec/#body-attributes | body `class` attribute}
27
+ *
28
+ * This class is named as a reference to {@link DOMTokenList}
29
+ * ({@link https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList | MDN}),
30
+ * with these similarities:
31
+ *
32
+ * - Represents a value whose serialization is a space-separated list.
33
+ * - Each member ("token") is a string (without whitespace).
34
+ * - Provides set-like semantics to determine presence of members.
35
+ * - Provides ordering semantics as determined by the serialization.
36
+ *
37
+ * This class differs from that prior art in that:
38
+ *
39
+ * - It provides a notion of "canonical" members. This is _mostly_ (but not
40
+ * entirely) intended as a convenience to client developers, automatically
41
+ * populating canonical/known tokens for a given parser type in
42
+ * editor-provided autocomplete, etc. **Importantly**, non-canonical tokens
43
+ * _are not ignored_ in either the {@link TokenList}'s types or runtime
44
+ * values.
45
+ *
46
+ * - Provided "canonical" members may also be used to specify
47
+ * {@link TokenListParserOptions.aliases | optional aliases}. (Example: when
48
+ * parsing "appearances", an alias might map an older deprecated appearance to
49
+ * a newer canonical equivalent.) **Importantly**, when a token matches an
50
+ * alias, both that alias _and the token as-specified_ will be present in the
51
+ * produced {@link TokenList}.
52
+ *
53
+ * - As a parser, it is intended to be read-only. The serialized format which it
54
+ * parses is _generally_ the source of truth (excepting e.g. aliases).
55
+ * Notably, and as mentioned above, ordering is determined by:
56
+ *
57
+ * - Iterating each member, as provided by the serialized representation
58
+ *
59
+ * - If that member corresponds to an alias, that alias is yielded first
60
+ *
61
+ * - Regardless of whether the member corresponds to an alias, the member is
62
+ * yielded as-specified
63
+ *
64
+ * - A parsed {@link TokenList} is intended to maximize convenience of read-only
65
+ * access. Despite many _conceptual similarities_, most of the
66
+ * {@link DOMTokenList} **interface** is eschewed in favor of two (mutually
67
+ * equivalent) access mechanisms:
68
+ *
69
+ * - `Iterable<Token>`, with the ordering semantics described above
70
+ * - `Record<Token, boolean>`
71
+ *
72
+ * \* This may change, as we refine requirements. In the future, we may
73
+ * introduce a notion of mutually exclusive tokens (e.g. "appearances" which
74
+ * cannot be used together), which may in turn utilize instance-defined ordering
75
+ * as part of that mechanism.
76
+ */
77
+ export declare class TokenListParser<CanonicalToken extends string, TokenAlias extends CanonicalToken = CanonicalToken> {
78
+ readonly canonicalTokens: readonly CanonicalToken[];
79
+ private readonly aliases;
80
+ constructor(canonicalTokens: readonly CanonicalToken[], options?: TokenListParserOptions<TokenAlias>);
81
+ parseFrom(element: Element, attributeName: TokenListAttributeName): TokenList<CanonicalToken>;
82
+ }
83
+ export type ParsedTokenList<Parser extends TokenListParser<any>> = Parser extends TokenListParser<infer CanonicalToken> ? TokenList<CanonicalToken> : never;
84
+ export {};
@@ -9,6 +9,10 @@ export interface ItemsetElement extends KnownAttributeLocalNamedElement<'itemset
9
9
  }
10
10
  export interface LabelElement extends LocalNamedElement<'label'> {
11
11
  }
12
+ export interface RepeatGroupLabelElement extends LabelElement {
13
+ getAttribute(name: 'form-definition-source'): 'repeat-group';
14
+ getAttribute(name: string): string;
15
+ }
12
16
  export interface RepeatElement extends KnownAttributeLocalNamedElement<'repeat', 'nodeset'> {
13
17
  }
14
18
  export interface ValueElement extends LocalNamedElement<'value'> {
@@ -17,5 +21,6 @@ export declare const getHintElement: (parent: Element) => HintElement | null;
17
21
  export declare const getItemElements: (parent: SelectElement) => readonly ItemElement[];
18
22
  export declare const getItemsetElement: (parent: Element) => ItemsetElement | null;
19
23
  export declare const getLabelElement: (parent: Element) => LabelElement | null;
24
+ export declare const getRepeatGroupLabelElement: (parent: Element) => RepeatGroupLabelElement | null;
20
25
  export declare const getRepeatElement: (parent: Element) => RepeatElement | null;
21
26
  export declare const getValueElement: (parent: ItemElement | ItemsetElement) => ValueElement | null;
@@ -1,13 +1,18 @@
1
1
  import { Accessor } from 'solid-js';
2
2
  import { DependentExpression, DependentExpressionResultType } from '../../expression/DependentExpression.ts';
3
3
  import { EvaluationContext } from '../../instance/internal-api/EvaluationContext.ts';
4
+ import { SubscribableDependency } from '../../instance/internal-api/SubscribableDependency.ts';
4
5
 
5
6
  interface ComputedExpressionResults {
6
7
  readonly boolean: boolean;
7
8
  readonly nodes: Node[];
9
+ readonly number: number;
8
10
  readonly string: string;
9
11
  }
10
12
  type EvaluatedExpression<Type extends DependentExpressionResultType> = ComputedExpressionResults[Type];
11
13
  type ComputedExpression<Type extends DependentExpressionResultType> = Accessor<EvaluatedExpression<Type>>;
12
- export declare const createComputedExpression: <Type extends "string" | "boolean" | "nodes">(context: EvaluationContext, dependentExpression: DependentExpression<Type>) => ComputedExpression<Type>;
14
+ interface CreateComputedExpressionOptions {
15
+ readonly arbitraryDependencies?: readonly SubscribableDependency[];
16
+ }
17
+ export declare const createComputedExpression: <Type extends DependentExpressionResultType>(context: EvaluationContext, dependentExpression: DependentExpression<Type>, options?: CreateComputedExpressionOptions) => ComputedExpression<Type>;
13
18
  export {};
@@ -0,0 +1,5 @@
1
+ import { Accessor } from 'solid-js';
2
+ import { EvaluationContext } from '../../instance/internal-api/EvaluationContext.ts';
3
+ import { BindComputation } from '../../model/BindComputation.ts';
4
+
5
+ export declare const createNoteReadonlyThunk: (context: EvaluationContext, readonlyDefinition: BindComputation<"readonly">) => Accessor<true>;
@@ -1,6 +1,7 @@
1
1
  import { AnyChildNode } from '../../instance/hierarchy.ts';
2
2
  import { NodeID } from '../../instance/identity.ts';
3
3
  import { ChildrenState } from './createChildrenState.ts';
4
+ import { ReactiveScope } from './scope.ts';
4
5
 
5
6
  export interface EncodedParentState {
6
7
  readonly children: readonly NodeID[];
@@ -16,4 +17,4 @@ export type MaterializedChildren<BaseState extends EncodedParentState, Child ext
16
17
  *
17
18
  * @see {@link createChildrenState} for further detail.
18
19
  */
19
- export declare const materializeCurrentStateChildren: <Child extends AnyChildNode, ParentState extends EncodedParentState>(currentState: ParentState, childrenState: ChildrenState<Child>) => MaterializedChildren<ParentState, Child>;
20
+ export declare const materializeCurrentStateChildren: <Child extends AnyChildNode, ParentState extends EncodedParentState>(scope: ReactiveScope, currentState: ParentState, childrenState: ChildrenState<Child>) => MaterializedChildren<ParentState, Child>;
@@ -16,7 +16,7 @@ export interface SharedNodeState<Spec extends StateSpec> {
16
16
  readonly currentState: CurrentState<Spec>;
17
17
  readonly setProperty: SetEnginePropertyState<Spec>;
18
18
  }
19
- interface SharedNodeStateOptions<Factory extends OpaqueReactiveObjectFactory, Spec extends StateSpec> {
19
+ export interface SharedNodeStateOptions<Factory extends OpaqueReactiveObjectFactory, Spec extends StateSpec> {
20
20
  readonly clientStateFactory: SpecifiedClientStateFactory<Factory, Spec>;
21
21
  }
22
22
  export declare const createSharedNodeState: <Factory extends OpaqueReactiveObjectFactory, Spec extends StateSpec>(scope: ReactiveScope, spec: Spec, options: SharedNodeStateOptions<Factory, Spec>) => SharedNodeState<Spec>;
@@ -110,7 +110,7 @@ export type StaticPropertySpec<T> = Exclude<T, NonStaticValue>;
110
110
  export type StatePropertySpec<T = any> = MutablePropertySpec<T> | ComputedPropertySpec<T> | StaticPropertySpec<T>;
111
111
  export declare const isMutablePropertySpec: <T>(propertySpec: StatePropertySpec<T>) => propertySpec is MutablePropertySpec<T>;
112
112
  export declare const isComputedPropertySpec: <T>(propertySpec: StatePropertySpec<T>) => propertySpec is ComputedPropertySpec<T>;
113
- export declare const isStaticPropertySpec: <T>(propertySpec: StatePropertySpec<T>) => propertySpec is Exclude<T, NonStaticValue>;
113
+ export declare const isStaticPropertySpec: <T>(propertySpec: StatePropertySpec<T>) => propertySpec is StaticPropertySpec<T>;
114
114
  export type StateSpec = Record<string, StatePropertySpec>;
115
115
  type SpecifiedStatePropertyValue<PropertySpec extends StatePropertySpec> = PropertySpec extends StatePropertySpec<infer T> ? T : never;
116
116
  type DerivedMutableKeys<Spec extends StateSpec> = {
@@ -1,6 +1,6 @@
1
1
  import { Accessor } from 'solid-js';
2
+ import { TextRange } from '../../../client/TextRange.ts';
2
3
  import { EvaluationContext } from '../../../instance/internal-api/EvaluationContext.ts';
3
- import { TextRange } from '../../../instance/text/TextRange.ts';
4
- import { ValueNodeDefinition } from '../../../model/ValueNodeDefinition.ts';
4
+ import { LeafNodeDefinition } from '../../../model/LeafNodeDefinition.ts';
5
5
 
6
- export declare const createFieldHint: (context: EvaluationContext, definition: ValueNodeDefinition) => Accessor<TextRange<'hint'> | null>;
6
+ export declare const createFieldHint: (context: EvaluationContext, definition: LeafNodeDefinition) => Accessor<TextRange<"hint", "form"> | null>;
@@ -1,6 +1,6 @@
1
1
  import { Accessor } from 'solid-js';
2
+ import { TextRange } from '../../../client/TextRange.ts';
2
3
  import { EvaluationContext } from '../../../instance/internal-api/EvaluationContext.ts';
3
- import { TextRange } from '../../../instance/text/TextRange.ts';
4
4
  import { AnyNodeDefinition } from '../../../model/NodeDefinition.ts';
5
5
 
6
- export declare const createNodeLabel: (context: EvaluationContext, definition: AnyNodeDefinition) => Accessor<TextRange<'label'> | null>;
6
+ export declare const createNodeLabel: (context: EvaluationContext, definition: AnyNodeDefinition) => Accessor<TextRange<"label", "form"> | null>;
@@ -0,0 +1,25 @@
1
+ import { Accessor } from 'solid-js';
2
+ import { TextRange } from '../../../client/TextRange.ts';
3
+ import { EvaluationContext } from '../../../instance/internal-api/EvaluationContext.ts';
4
+ import { NoteTextDefinition } from '../../../parse/NoteNodeDefinition.ts';
5
+
6
+ export type NoteTextRole = 'label' | 'hint';
7
+ export type ComputedNoteText<Role extends NoteTextRole = NoteTextRole> = Accessor<TextRange<Role, 'form'>>;
8
+ interface BaseNoteText {
9
+ readonly role: NoteTextRole;
10
+ readonly label: ComputedNoteText<'label'> | null;
11
+ readonly hint: ComputedNoteText<'hint'> | null;
12
+ }
13
+ interface LabelNoteText extends BaseNoteText {
14
+ readonly role: 'label';
15
+ readonly label: ComputedNoteText<'label'>;
16
+ readonly hint: null;
17
+ }
18
+ interface HintNoteText extends BaseNoteText {
19
+ readonly role: 'hint';
20
+ readonly label: null;
21
+ readonly hint: ComputedNoteText<'hint'>;
22
+ }
23
+ export type NoteTextComputation = LabelNoteText | HintNoteText;
24
+ export declare const createNoteText: (context: EvaluationContext, noteTextDefinition: NoteTextDefinition) => NoteTextComputation;
25
+ export {};
@@ -1,12 +1,10 @@
1
1
  import { Accessor } from 'solid-js';
2
- import { TextElementDefinition } from '../../../body/text/TextElementDefinition.ts';
2
+ import { TextRole } from '../../../client/TextRange.ts';
3
3
  import { EvaluationContext } from '../../../instance/internal-api/EvaluationContext.ts';
4
- import { TextRange, TextRole } from '../../../instance/text/TextRange.ts';
4
+ import { TextRange } from '../../../instance/text/TextRange.ts';
5
+ import { TextRangeDefinition } from '../../../parse/text/abstract/TextRangeDefinition.ts';
5
6
 
6
- interface CreateTextRangeOptions<FallbackValue extends string | null> {
7
- readonly fallbackValue?: FallbackValue;
8
- }
9
- type ComputedTextRange<Role extends TextRole, Definition extends TextElementDefinition<Role> | null, FallbackValue extends string | null> = Accessor<Definition extends null ? FallbackValue extends null ? TextRange<Role> | null : TextRange<Role> : TextRange<Role>>;
7
+ type ComputedFormTextRange<Role extends TextRole> = Accessor<TextRange<Role, 'form'>>;
10
8
  /**
11
9
  * Creates a text range (e.g. label or hint) from the provided definition,
12
10
  * reactive to:
@@ -16,5 +14,5 @@ type ComputedTextRange<Role extends TextRole, Definition extends TextElementDefi
16
14
  *
17
15
  * @todo This does not yet handle itext translations **with** outputs!
18
16
  */
19
- export declare const createTextRange: <Role extends TextRole, Definition extends TextElementDefinition<Role> | null, FallbackValue extends string | null = null>(context: EvaluationContext, role: Role, definition: Definition, options?: CreateTextRangeOptions<FallbackValue>) => ComputedTextRange<Role, Definition, FallbackValue>;
17
+ export declare const createTextRange: <Role extends TextRole>(context: EvaluationContext, role: Role, definition: TextRangeDefinition<Role>) => ComputedFormTextRange<Role>;
20
18
  export {};
@@ -0,0 +1,9 @@
1
+ import { OpaqueReactiveObjectFactory } from '../../../client/OpaqueReactiveObjectFactory.ts';
2
+ import { AncestorNodeValidationState } from '../../../client/validation.ts';
3
+ import { AnyParentNode } from '../../../instance/hierarchy.ts';
4
+
5
+ interface AggregatedViolationsOptions {
6
+ readonly clientStateFactory: OpaqueReactiveObjectFactory<AncestorNodeValidationState>;
7
+ }
8
+ export declare const createAggregatedViolations: (context: AnyParentNode, options: AggregatedViolationsOptions) => AncestorNodeValidationState;
9
+ export {};
@@ -0,0 +1,18 @@
1
+ import { Accessor } from 'solid-js';
2
+ import { OpaqueReactiveObjectFactory } from '../../../client/OpaqueReactiveObjectFactory.ts';
3
+ import { AnyViolation, ConditionValidation, ValidationCondition } from '../../../client/validation.ts';
4
+ import { ValidationContext } from '../../../instance/internal-api/ValidationContext.ts';
5
+ import { SharedNodeState, SharedNodeStateOptions } from '../node-state/createSharedNodeState.ts';
6
+
7
+ type ComputedConditionValidation<Condition extends ValidationCondition> = Accessor<ConditionValidation<Condition>>;
8
+ type ComputedViolation = Accessor<AnyViolation | null>;
9
+ interface ValidationStateSpec {
10
+ readonly constraint: ComputedConditionValidation<'constraint'>;
11
+ readonly required: ComputedConditionValidation<'required'>;
12
+ readonly violation: ComputedViolation;
13
+ }
14
+ export type SharedValidationState = SharedNodeState<ValidationStateSpec>;
15
+ interface ValidationStateOptions<Factory extends OpaqueReactiveObjectFactory> extends SharedNodeStateOptions<Factory, ValidationStateSpec> {
16
+ }
17
+ export declare const createValidationState: <Factory extends OpaqueReactiveObjectFactory>(context: ValidationContext, options: ValidationStateOptions<Factory>) => SharedValidationState;
18
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { XFormDataType } from '../XFormDataType.ts';
2
2
  import { XFormDefinition } from '../XFormDefinition.ts';
3
3
  import { DependencyContext } from '../expression/DependencyContext.ts';
4
- import { DependentExpression } from '../expression/DependentExpression.ts';
4
+ import { MessageDefinition } from '../parse/text/MessageDefinition.ts';
5
5
  import { BindComputation } from './BindComputation.ts';
6
6
  import { BindElement } from './BindElement.ts';
7
7
  import { ModelDefinition } from './ModelDefinition.ts';
@@ -21,7 +21,9 @@ export declare class BindDefinition extends DependencyContext {
21
21
  /**
22
22
  * Diverges from {@link https://github.com/getodk/javarosa/blob/059321160e6f8dbb3e81d9add61d68dd35b13cc8/dag.md | JavaRosa's}, which excludes `constraint` expressions. We compute `constraint` dependencies like the other <bind> computation expressions, but explicitly ignore self-references (this is currently handled by {@link BindComputation}, via its {@link DependentExpression} parent class).
23
23
  */
24
- readonly constraint: BindComputation<'constraint'> & DependentExpression<'boolean'>;
24
+ readonly constraint: BindComputation<'constraint'>;
25
+ readonly constraintMsg: MessageDefinition<'constraintMsg'> | null;
26
+ readonly requiredMsg: MessageDefinition<'requiredMsg'> | null;
25
27
  readonly saveIncomplete: BindComputation<'saveIncomplete'>;
26
28
  protected _parentBind: BindDefinition | null | undefined;
27
29
  get parentBind(): BindDefinition | null;
@@ -3,4 +3,5 @@ export interface BindElement {
3
3
  readonly localName: 'bind';
4
4
  getAttribute(name: 'nodeset'): BindNodeset;
5
5
  getAttribute(name: string): string | null;
6
+ getAttributeNS(namespaceURI: string | null, localName: string): string | null;
6
7
  }
@@ -1,11 +1,10 @@
1
1
  import { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
2
- import { RepeatDefinition } from '../body/RepeatDefinition.ts';
3
2
  import { BindDefinition } from './BindDefinition.ts';
4
3
  import { ModelNode, NodeChildren, NodeDefaultValue, NodeDefinition, NodeDefinitionType, NodeInstances, NodeParent } from './NodeDefinition.ts';
5
4
  import { RootDefinition } from './RootDefinition.ts';
6
5
 
7
6
  export type DescendentNodeType = Exclude<NodeDefinitionType, 'root'>;
8
- type DescendentNodeBodyElement = AnyBodyElementDefinition | RepeatDefinition;
7
+ type DescendentNodeBodyElement = AnyBodyElementDefinition;
9
8
  export declare abstract class DescendentNodeDefinition<Type extends DescendentNodeType, BodyElement extends DescendentNodeBodyElement | null = DescendentNodeBodyElement | null> implements NodeDefinition<Type> {
10
9
  readonly parent: NodeParent<Type>;
11
10
  readonly bind: BindDefinition;
@@ -1,12 +1,11 @@
1
- import { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
2
- import { AnyControlDefinition } from '../body/control/ControlDefinition.ts';
1
+ import { AnyBodyElementDefinition, ControlElementDefinition } from '../body/BodyDefinition.ts';
3
2
  import { BindDefinition } from './BindDefinition.ts';
4
3
  import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
5
4
  import { NodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
6
5
 
7
- export declare class ValueNodeDefinition extends DescendentNodeDefinition<'value-node', AnyControlDefinition | null> implements NodeDefinition<'value-node'> {
6
+ export declare class LeafNodeDefinition extends DescendentNodeDefinition<'leaf-node', ControlElementDefinition | null> implements NodeDefinition<'leaf-node'> {
8
7
  readonly node: Element;
9
- readonly type = "value-node";
8
+ readonly type = "leaf-node";
10
9
  readonly nodeName: string;
11
10
  readonly children: null;
12
11
  readonly instances: null;