@getodk/xforms-engine 0.15.0 → 0.16.1

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 (111) hide show
  1. package/dist/client/AttributeNode.d.ts +4 -6
  2. package/dist/client/BaseNode.d.ts +5 -0
  3. package/dist/client/form/FormInstanceConfig.d.ts +15 -0
  4. package/dist/index.js +654 -429
  5. package/dist/index.js.map +1 -1
  6. package/dist/instance/Attribute.d.ts +13 -19
  7. package/dist/instance/Group.d.ts +2 -1
  8. package/dist/instance/InputControl.d.ts +5 -0
  9. package/dist/instance/ModelValue.d.ts +4 -0
  10. package/dist/instance/Note.d.ts +4 -0
  11. package/dist/instance/PrimaryInstance.d.ts +3 -2
  12. package/dist/instance/RangeControl.d.ts +4 -0
  13. package/dist/instance/RankControl.d.ts +5 -1
  14. package/dist/instance/Root.d.ts +2 -1
  15. package/dist/instance/SelectControl.d.ts +5 -1
  16. package/dist/instance/TriggerControl.d.ts +4 -0
  17. package/dist/instance/UploadControl.d.ts +3 -2
  18. package/dist/instance/abstract/DescendantNode.d.ts +5 -4
  19. package/dist/instance/abstract/InstanceNode.d.ts +6 -5
  20. package/dist/instance/abstract/ValueNode.d.ts +2 -1
  21. package/dist/instance/attachments/buildAttributes.d.ts +6 -2
  22. package/dist/instance/hierarchy.d.ts +2 -2
  23. package/dist/instance/internal-api/AttributeContext.d.ts +6 -0
  24. package/dist/instance/internal-api/InstanceConfig.d.ts +2 -0
  25. package/dist/instance/internal-api/InstanceValueContext.d.ts +6 -0
  26. package/dist/instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.d.ts +0 -1
  27. package/dist/instance/internal-api/serialization/ClientReactiveSerializableValueNode.d.ts +4 -0
  28. package/dist/integration/xpath/adapter/XFormsXPathNode.d.ts +1 -1
  29. package/dist/integration/xpath/adapter/kind.d.ts +5 -3
  30. package/dist/integration/xpath/adapter/traversal.d.ts +3 -3
  31. package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +1 -0
  32. package/dist/lib/codecs/items/SingleValueItemCodec.d.ts +1 -1
  33. package/dist/lib/reactivity/createInstanceValueState.d.ts +4 -1
  34. package/dist/lib/reactivity/node-state/createSharedNodeState.d.ts +2 -2
  35. package/dist/lib/xml-serialization.d.ts +1 -1
  36. package/dist/parse/XFormDOM.d.ts +3 -0
  37. package/dist/parse/expression/ActionComputationExpression.d.ts +4 -0
  38. package/dist/parse/model/ActionDefinition.d.ts +15 -0
  39. package/dist/parse/model/AttributeDefinition.d.ts +5 -1
  40. package/dist/parse/model/BindPreloadDefinition.d.ts +6 -10
  41. package/dist/parse/model/Event.d.ts +8 -0
  42. package/dist/parse/model/LeafNodeDefinition.d.ts +5 -2
  43. package/dist/parse/model/ModelActionMap.d.ts +9 -0
  44. package/dist/parse/model/ModelDefinition.d.ts +8 -1
  45. package/dist/parse/model/NoteNodeDefinition.d.ts +3 -2
  46. package/dist/parse/model/RangeNodeDefinition.d.ts +2 -1
  47. package/dist/parse/model/RootDefinition.d.ts +1 -0
  48. package/dist/solid.js +654 -429
  49. package/dist/solid.js.map +1 -1
  50. package/package.json +21 -17
  51. package/src/client/AttributeNode.ts +4 -6
  52. package/src/client/BaseNode.ts +6 -0
  53. package/src/client/form/FormInstanceConfig.ts +17 -0
  54. package/src/client/validation.ts +1 -1
  55. package/src/entrypoints/FormInstance.ts +1 -0
  56. package/src/instance/Attribute.ts +43 -59
  57. package/src/instance/Group.ts +5 -6
  58. package/src/instance/InputControl.ts +16 -1
  59. package/src/instance/ModelValue.ts +16 -1
  60. package/src/instance/Note.ts +15 -1
  61. package/src/instance/PrimaryInstance.ts +8 -10
  62. package/src/instance/RangeControl.ts +15 -1
  63. package/src/instance/RankControl.ts +17 -2
  64. package/src/instance/Root.ts +5 -6
  65. package/src/instance/SelectControl.ts +16 -2
  66. package/src/instance/TriggerControl.ts +15 -1
  67. package/src/instance/UploadControl.ts +9 -8
  68. package/src/instance/abstract/DescendantNode.ts +4 -8
  69. package/src/instance/abstract/InstanceNode.ts +7 -5
  70. package/src/instance/abstract/ValueNode.ts +2 -1
  71. package/src/instance/attachments/buildAttributes.ts +15 -4
  72. package/src/instance/children/childrenInitOptions.ts +2 -1
  73. package/src/instance/children/normalizeChildInitOptions.ts +1 -1
  74. package/src/instance/hierarchy.ts +2 -2
  75. package/src/instance/internal-api/AttributeContext.ts +6 -0
  76. package/src/instance/internal-api/InstanceConfig.ts +6 -1
  77. package/src/instance/internal-api/InstanceValueContext.ts +6 -0
  78. package/src/instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.ts +0 -1
  79. package/src/instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts +4 -0
  80. package/src/instance/repeat/RepeatInstance.ts +3 -4
  81. package/src/integration/xpath/adapter/XFormsXPathNode.ts +1 -0
  82. package/src/integration/xpath/adapter/engineDOMAdapter.ts +2 -2
  83. package/src/integration/xpath/adapter/kind.ts +6 -1
  84. package/src/integration/xpath/adapter/names.ts +1 -0
  85. package/src/integration/xpath/adapter/traversal.ts +5 -6
  86. package/src/integration/xpath/static-dom/StaticAttribute.ts +1 -0
  87. package/src/lib/client-reactivity/instance-state/createValueNodeInstanceState.ts +2 -1
  88. package/src/lib/client-reactivity/instance-state/prepareInstancePayload.ts +1 -0
  89. package/src/lib/codecs/NoteCodec.ts +1 -1
  90. package/src/lib/codecs/items/SingleValueItemCodec.ts +1 -3
  91. package/src/lib/reactivity/createInstanceValueState.ts +177 -52
  92. package/src/lib/reactivity/node-state/createSharedNodeState.ts +2 -2
  93. package/src/lib/xml-serialization.ts +9 -1
  94. package/src/parse/XFormDOM.ts +9 -0
  95. package/src/parse/body/GroupElementDefinition.ts +1 -1
  96. package/src/parse/body/control/InputControlDefinition.ts +1 -1
  97. package/src/parse/expression/ActionComputationExpression.ts +12 -0
  98. package/src/parse/model/ActionDefinition.ts +70 -0
  99. package/src/parse/model/AttributeDefinition.ts +10 -2
  100. package/src/parse/model/AttributeDefinitionMap.ts +1 -1
  101. package/src/parse/model/BindDefinition.ts +1 -6
  102. package/src/parse/model/BindPreloadDefinition.ts +44 -12
  103. package/src/parse/model/Event.ts +9 -0
  104. package/src/parse/model/LeafNodeDefinition.ts +5 -1
  105. package/src/parse/model/ModelActionMap.ts +37 -0
  106. package/src/parse/model/ModelDefinition.ts +18 -3
  107. package/src/parse/model/NoteNodeDefinition.ts +5 -2
  108. package/src/parse/model/RangeNodeDefinition.ts +5 -2
  109. package/src/parse/model/RootDefinition.ts +22 -4
  110. package/dist/lib/reactivity/createAttributeValueState.d.ts +0 -15
  111. package/src/lib/reactivity/createAttributeValueState.ts +0 -189
@@ -11,6 +11,10 @@ import type { XFormsXPathElement } from '../integration/xpath/adapter/XFormsXPat
11
11
  import type { StaticLeafElement } from '../integration/xpath/static-dom/StaticElement.ts';
12
12
  import { RangeCodec } from '../lib/codecs/RangeCodec.ts';
13
13
  import { getSharedValueCodec } from '../lib/codecs/getSharedValueCodec.ts';
14
+ import {
15
+ createAttributeState,
16
+ type AttributeState,
17
+ } from '../lib/reactivity/createAttributeState.ts';
14
18
  import type { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
15
19
  import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
16
20
  import type { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
@@ -22,8 +26,10 @@ import type {
22
26
  RangeNodeDefinition,
23
27
  RangeValueType,
24
28
  } from '../parse/model/RangeNodeDefinition.ts';
29
+ import type { Attribute } from './Attribute.ts';
25
30
  import type { Root } from './Root.ts';
26
31
  import { ValueNode, type ValueNodeStateSpec } from './abstract/ValueNode.ts';
32
+ import { buildAttributes } from './attachments/buildAttributes.ts';
27
33
  import type { GeneralParentNode } from './hierarchy.ts';
28
34
  import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
29
35
  import type { ValidationContext } from './internal-api/ValidationContext.ts';
@@ -64,6 +70,7 @@ export class RangeControl<V extends RangeValueType = RangeValueType>
64
70
  // InstanceNode
65
71
  protected readonly state: SharedNodeState<RangeControlStateSpec<V>>;
66
72
  protected readonly engineState: EngineState<RangeControlStateSpec<V>>;
73
+ readonly attributeState: AttributeState;
67
74
 
68
75
  // RangeNode
69
76
  readonly nodeType = 'range';
@@ -82,6 +89,7 @@ export class RangeControl<V extends RangeValueType = RangeValueType>
82
89
  super(parent, instanceNode, definition, codec);
83
90
 
84
91
  this.appearances = definition.bodyElement.appearances;
92
+ this.attributeState = createAttributeState(this.scope);
85
93
 
86
94
  const state = createSharedNodeState(
87
95
  this.scope,
@@ -94,7 +102,7 @@ export class RangeControl<V extends RangeValueType = RangeValueType>
94
102
  label: createNodeLabel(this, definition),
95
103
  hint: createFieldHint(this, definition),
96
104
  children: null,
97
- attributes: null,
105
+ attributes: this.attributeState.getAttributes,
98
106
  valueOptions: null,
99
107
  value: this.valueState,
100
108
  instanceValue: this.getInstanceValue,
@@ -102,6 +110,8 @@ export class RangeControl<V extends RangeValueType = RangeValueType>
102
110
  this.instanceConfig
103
111
  );
104
112
 
113
+ this.attributeState.setAttributes(buildAttributes(this));
114
+
105
115
  this.state = state;
106
116
  this.engineState = state.engineState;
107
117
  this.currentState = state.currentState;
@@ -112,6 +122,10 @@ export class RangeControl<V extends RangeValueType = RangeValueType>
112
122
 
113
123
  return this.root;
114
124
  }
125
+
126
+ override getAttributes(): readonly Attribute[] {
127
+ return this.attributeState.getAttributes();
128
+ }
115
129
  }
116
130
 
117
131
  // prettier-ignore
@@ -1,4 +1,4 @@
1
- import { type XPathChoiceNode, XPathNodeKindKey } from '@getodk/xpath';
1
+ import { XPathNodeKindKey, type XPathChoiceNode } from '@getodk/xpath';
2
2
  import type { Accessor } from 'solid-js';
3
3
  import { createMemo } from 'solid-js';
4
4
  import type { RankDefinition, RankItem, RankNode, RankValueOptions } from '../client/RankNode.ts';
@@ -10,6 +10,10 @@ import type { XFormsXPathElement } from '../integration/xpath/adapter/XFormsXPat
10
10
  import type { StaticLeafElement } from '../integration/xpath/static-dom/StaticElement.ts';
11
11
  import { sharedValueCodecs } from '../lib/codecs/getSharedValueCodec.ts';
12
12
  import { MultipleValueItemCodec } from '../lib/codecs/items/MultipleValueItemCodec.ts';
13
+ import {
14
+ createAttributeState,
15
+ type AttributeState,
16
+ } from '../lib/reactivity/createAttributeState.ts';
13
17
  import { createItemCollection } from '../lib/reactivity/createItemCollection.ts';
14
18
  import type { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
15
19
  import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
@@ -19,9 +23,11 @@ import { createFieldHint } from '../lib/reactivity/text/createFieldHint.ts';
19
23
  import { createNodeLabel } from '../lib/reactivity/text/createNodeLabel.ts';
20
24
  import type { SimpleAtomicState } from '../lib/reactivity/types.ts';
21
25
  import type { UnknownAppearanceDefinition } from '../parse/body/appearance/unknownAppearanceParser.ts';
26
+ import type { Attribute } from './Attribute.ts';
22
27
  import type { Root } from './Root.ts';
23
28
  import type { ValueNodeStateSpec } from './abstract/ValueNode.ts';
24
29
  import { ValueNode } from './abstract/ValueNode.ts';
30
+ import { buildAttributes } from './attachments/buildAttributes.ts';
25
31
  import type { GeneralParentNode } from './hierarchy.ts';
26
32
  import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
27
33
  import type { ValidationContext } from './internal-api/ValidationContext.ts';
@@ -94,6 +100,7 @@ export class RankControl
94
100
  // InstanceNode
95
101
  protected readonly state: SharedNodeState<RankControlStateSpec>;
96
102
  protected readonly engineState: EngineState<RankControlStateSpec>;
103
+ readonly attributeState: AttributeState;
97
104
 
98
105
  // RankNode
99
106
  readonly nodeType = 'rank';
@@ -123,6 +130,8 @@ export class RankControl
123
130
  const baseValueState = this.valueState;
124
131
  const [baseGetValue, setValue] = baseValueState;
125
132
 
133
+ this.attributeState = createAttributeState(this.scope);
134
+
126
135
  /**
127
136
  * @ToDo As new value options become available, they're not yet in the
128
137
  * `currentValues` state. This appends them. We intend to change this
@@ -174,7 +183,7 @@ export class RankControl
174
183
  label: createNodeLabel(this, definition),
175
184
  hint: createFieldHint(this, definition),
176
185
  children: null,
177
- attributes: null,
186
+ attributes: this.attributeState.getAttributes,
178
187
  valueOptions,
179
188
  value: valueState,
180
189
  instanceValue: this.getInstanceValue,
@@ -182,11 +191,17 @@ export class RankControl
182
191
  this.instanceConfig
183
192
  );
184
193
 
194
+ this.attributeState.setAttributes(buildAttributes(this));
195
+
185
196
  this.state = state;
186
197
  this.engineState = state.engineState;
187
198
  this.currentState = state.currentState;
188
199
  }
189
200
 
201
+ override getAttributes(): readonly Attribute[] {
202
+ return this.attributeState.getAttributes();
203
+ }
204
+
190
205
  getValueLabel(value: string): TextRange<'item-label'> | null {
191
206
  const valueOption = this.currentState.valueOptions.find((item) => item.value === value);
192
207
  return valueOption?.label ?? null;
@@ -63,7 +63,6 @@ export class Root
63
63
  ClientReactiveSerializableParentNode<GeneralChildNode>
64
64
  {
65
65
  private readonly childrenState: ChildrenState<GeneralChildNode>;
66
- private readonly attributeState: AttributeState;
67
66
 
68
67
  // XFormsXPathElement
69
68
  override readonly [XPathNodeKindKey] = 'element';
@@ -71,6 +70,7 @@ export class Root
71
70
  // DescendantNode
72
71
  protected readonly state: SharedNodeState<RootStateSpec>;
73
72
  protected readonly engineState: EngineState<RootStateSpec>;
73
+ readonly attributeState: AttributeState;
74
74
 
75
75
  override readonly hasReadonlyAncestor = () => false;
76
76
  override readonly isSelfReadonly = () => false;
@@ -103,10 +103,9 @@ export class Root
103
103
  this.classes = parent.classes;
104
104
 
105
105
  const childrenState = createChildrenState<Root, GeneralChildNode>(this);
106
- const attributeState = createAttributeState(this.scope);
106
+ this.attributeState = createAttributeState(this.scope);
107
107
 
108
108
  this.childrenState = childrenState;
109
- this.attributeState = attributeState;
110
109
  this.languages = parent.languages;
111
110
 
112
111
  const state = createSharedNodeState(
@@ -122,7 +121,7 @@ export class Root
122
121
  valueOptions: null,
123
122
  value: null,
124
123
  children: childrenState.childIds,
125
- attributes: attributeState.getAttributes,
124
+ attributes: this.attributeState.getAttributes,
126
125
  },
127
126
  this.instanceConfig
128
127
  );
@@ -136,7 +135,7 @@ export class Root
136
135
  );
137
136
 
138
137
  childrenState.setChildren(buildChildren(this));
139
- attributeState.setAttributes(buildAttributes(this));
138
+ this.attributeState.setAttributes(buildAttributes(this));
140
139
  this.validationState = createAggregatedViolations(this, this.instanceConfig);
141
140
  this.instanceState = createRootInstanceState(this);
142
141
  }
@@ -145,7 +144,7 @@ export class Root
145
144
  return this.childrenState.getChildren();
146
145
  }
147
146
 
148
- getAttributes(): readonly Attribute[] {
147
+ override getAttributes(): readonly Attribute[] {
149
148
  return this.attributeState.getAttributes();
150
149
  }
151
150
 
@@ -1,4 +1,4 @@
1
- import { type XPathChoiceNode, XPathNodeKindKey } from '@getodk/xpath';
1
+ import { XPathNodeKindKey, type XPathChoiceNode } from '@getodk/xpath';
2
2
  import type { Accessor } from 'solid-js';
3
3
  import { createMemo } from 'solid-js';
4
4
  import type {
@@ -14,6 +14,10 @@ import { SelectValueTypeError } from '../error/SelectValueTypeError.ts';
14
14
  import type { XFormsXPathElement } from '../integration/xpath/adapter/XFormsXPathNode.ts';
15
15
  import type { StaticLeafElement } from '../integration/xpath/static-dom/StaticElement.ts';
16
16
  import { getSelectCodec } from '../lib/codecs/getSelectCodec.ts';
17
+ import {
18
+ createAttributeState,
19
+ type AttributeState,
20
+ } from '../lib/reactivity/createAttributeState.ts';
17
21
  import { createItemCollection } from '../lib/reactivity/createItemCollection.ts';
18
22
  import type { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
19
23
  import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
@@ -23,9 +27,11 @@ import { createFieldHint } from '../lib/reactivity/text/createFieldHint.ts';
23
27
  import { createNodeLabel } from '../lib/reactivity/text/createNodeLabel.ts';
24
28
  import type { SimpleAtomicState } from '../lib/reactivity/types.ts';
25
29
  import type { SelectType } from '../parse/body/control/SelectControlDefinition.ts';
30
+ import type { Attribute } from './Attribute.ts';
26
31
  import type { Root } from './Root.ts';
27
32
  import type { ValueNodeStateSpec } from './abstract/ValueNode.ts';
28
33
  import { ValueNode } from './abstract/ValueNode.ts';
34
+ import { buildAttributes } from './attachments/buildAttributes.ts';
29
35
  import type { GeneralParentNode } from './hierarchy.ts';
30
36
  import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
31
37
  import type { ValidationContext } from './internal-api/ValidationContext.ts';
@@ -89,6 +95,7 @@ export class SelectControl
89
95
  // InstanceNode
90
96
  protected readonly state: SharedNodeState<SelectControlStateSpec>;
91
97
  protected readonly engineState: EngineState<SelectControlStateSpec>;
98
+ readonly attributeState: AttributeState;
92
99
 
93
100
  // SelectNode
94
101
  readonly nodeType = 'select';
@@ -108,6 +115,7 @@ export class SelectControl
108
115
 
109
116
  this.appearances = definition.bodyElement.appearances;
110
117
  this.selectType = definition.bodyElement.type;
118
+ this.attributeState = createAttributeState(this.scope);
111
119
 
112
120
  const valueOptions = createItemCollection(this);
113
121
 
@@ -153,7 +161,7 @@ export class SelectControl
153
161
  label: createNodeLabel(this, definition),
154
162
  hint: createFieldHint(this, definition),
155
163
  children: null,
156
- attributes: null,
164
+ attributes: this.attributeState.getAttributes,
157
165
  valueOptions,
158
166
  value: valueState,
159
167
  instanceValue: this.getInstanceValue,
@@ -162,6 +170,8 @@ export class SelectControl
162
170
  this.instanceConfig
163
171
  );
164
172
 
173
+ this.attributeState.setAttributes(buildAttributes(this));
174
+
165
175
  this.state = state;
166
176
  this.engineState = state.engineState;
167
177
  this.currentState = state.currentState;
@@ -238,4 +248,8 @@ export class SelectControl
238
248
  const option = this.mapOptionsByValue().get(value);
239
249
  return option?.label?.asString ?? null;
240
250
  }
251
+
252
+ override getAttributes(): readonly Attribute[] {
253
+ return this.attributeState.getAttributes();
254
+ }
241
255
  }
@@ -8,6 +8,10 @@ import type { XFormsXPathElement } from '../integration/xpath/adapter/XFormsXPat
8
8
  import type { StaticLeafElement } from '../integration/xpath/static-dom/StaticElement.ts';
9
9
  import type { TriggerInputValue, TriggerRuntimeValue } from '../lib/codecs/TriggerCodec.ts';
10
10
  import { TriggerCodec } from '../lib/codecs/TriggerCodec.ts';
11
+ import {
12
+ createAttributeState,
13
+ type AttributeState,
14
+ } from '../lib/reactivity/createAttributeState.ts';
11
15
  import type { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
12
16
  import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
13
17
  import type { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
@@ -15,8 +19,10 @@ import { createSharedNodeState } from '../lib/reactivity/node-state/createShared
15
19
  import { createFieldHint } from '../lib/reactivity/text/createFieldHint.ts';
16
20
  import { createNodeLabel } from '../lib/reactivity/text/createNodeLabel.ts';
17
21
  import type { UnknownAppearanceDefinition } from '../parse/body/appearance/unknownAppearanceParser.ts';
22
+ import type { Attribute } from './Attribute.ts';
18
23
  import type { Root } from './Root.ts';
19
24
  import { ValueNode, type ValueNodeStateSpec } from './abstract/ValueNode.ts';
25
+ import { buildAttributes } from './attachments/buildAttributes.ts';
20
26
  import type { GeneralParentNode } from './hierarchy.ts';
21
27
  import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
22
28
  import type { ValidationContext } from './internal-api/ValidationContext.ts';
@@ -73,6 +79,7 @@ export class TriggerControl
73
79
  // InstanceNode
74
80
  protected readonly state: SharedNodeState<TriggerControlStateSpec>;
75
81
  protected readonly engineState: EngineState<TriggerControlStateSpec>;
82
+ readonly attributeState: AttributeState;
76
83
 
77
84
  // TriggerNode
78
85
  readonly nodeType = 'trigger';
@@ -88,6 +95,7 @@ export class TriggerControl
88
95
  super(parent, instanceNode, definition, codec);
89
96
 
90
97
  this.appearances = definition.bodyElement.appearances;
98
+ this.attributeState = createAttributeState(this.scope);
91
99
 
92
100
  const state = createSharedNodeState(
93
101
  this.scope,
@@ -100,7 +108,7 @@ export class TriggerControl
100
108
  label: createNodeLabel(this, definition),
101
109
  hint: createFieldHint(this, definition),
102
110
  children: null,
103
- attributes: null,
111
+ attributes: this.attributeState.getAttributes,
104
112
  valueOptions: null,
105
113
  value: this.valueState,
106
114
  instanceValue: this.getInstanceValue,
@@ -108,11 +116,17 @@ export class TriggerControl
108
116
  this.instanceConfig
109
117
  );
110
118
 
119
+ this.attributeState.setAttributes(buildAttributes(this));
120
+
111
121
  this.state = state;
112
122
  this.engineState = state.engineState;
113
123
  this.currentState = state.currentState;
114
124
  }
115
125
 
126
+ override getAttributes(): readonly Attribute[] {
127
+ return this.attributeState.getAttributes();
128
+ }
129
+
116
130
  // TriggerNode
117
131
  setValue(value: TriggerInputValue): Root {
118
132
  this.setValueState(value);
@@ -32,6 +32,7 @@ import type {
32
32
  InstanceAttachment,
33
33
  InstanceAttachmentRuntimeValue,
34
34
  } from './attachments/InstanceAttachment.ts';
35
+ import { buildAttributes } from './attachments/buildAttributes.ts';
35
36
  import type { GeneralParentNode } from './hierarchy.ts';
36
37
  import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
37
38
  import type { InstanceAttachmentContext } from './internal-api/InstanceAttachmentContext.ts';
@@ -101,7 +102,6 @@ export class UploadControl
101
102
 
102
103
  private readonly validation: SharedValidationState;
103
104
  private readonly instanceAttachment: InstanceAttachment;
104
- private readonly attributeState: AttributeState;
105
105
 
106
106
  // XFormsXPathElement
107
107
  override readonly [XPathNodeKindKey] = 'element';
@@ -110,6 +110,7 @@ export class UploadControl
110
110
  // InstanceNode
111
111
  protected readonly state: SharedNodeState<UploadControlStateSpec>;
112
112
  protected readonly engineState: EngineState<UploadControlStateSpec>;
113
+ readonly attributeState: AttributeState;
113
114
 
114
115
  // InstanceValueContext
115
116
  readonly decodeInstanceValue: DecodeInstanceValue;
@@ -140,8 +141,7 @@ export class UploadControl
140
141
  const instanceAttachment = createInstanceAttachment(this);
141
142
 
142
143
  this.instanceAttachment = instanceAttachment;
143
- const attributeState = createAttributeState(this.scope);
144
- this.attributeState = attributeState;
144
+ this.attributeState = createAttributeState(this.scope);
145
145
  this.decodeInstanceValue = instanceAttachment.decodeInstanceValue;
146
146
  this.getXPathValue = instanceAttachment.getInstanceValue;
147
147
 
@@ -158,7 +158,7 @@ export class UploadControl
158
158
  children: null,
159
159
  valueOptions: null,
160
160
  value: instanceAttachment.valueState,
161
- attributes: attributeState.getAttributes,
161
+ attributes: this.attributeState.getAttributes,
162
162
  instanceValue: instanceAttachment.getInstanceValue,
163
163
  },
164
164
  this.instanceConfig
@@ -168,6 +168,7 @@ export class UploadControl
168
168
  this.engineState = state.engineState;
169
169
  this.currentState = state.currentState;
170
170
  this.validation = createValidationState(this, this.instanceConfig);
171
+ this.attributeState.setAttributes(buildAttributes(this));
171
172
  this.instanceState = createValueNodeInstanceState(this);
172
173
  }
173
174
 
@@ -185,14 +186,14 @@ export class UploadControl
185
186
  return [];
186
187
  }
187
188
 
189
+ override getAttributes(): readonly Attribute[] {
190
+ return this.attributeState.getAttributes();
191
+ }
192
+
188
193
  // UploadNode
189
194
  setValue(value: InstanceAttachmentRuntimeValue): Root {
190
195
  this.instanceAttachment.setValue(value);
191
196
 
192
197
  return this.root;
193
198
  }
194
-
195
- getAttributes(): readonly Attribute[] {
196
- return this.attributeState.getAttributes();
197
- }
198
199
  }
@@ -11,12 +11,13 @@ import type {
11
11
  } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
12
12
  import { XFORMS_XPATH_NODE_RANGE_KIND } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
13
13
  import type { EngineXPathEvaluator } from '../../integration/xpath/EngineXPathEvaluator.ts';
14
+ import type { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
14
15
  import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
15
16
  import { createComputedExpression } from '../../lib/reactivity/createComputedExpression.ts';
16
17
  import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
17
18
  import type { AnyNodeDefinition } from '../../parse/model/NodeDefinition.ts';
18
19
  import type { DescendantNodeInitOptions } from '../children/DescendantNodeInitOptions.ts';
19
- import type { AnyChildNode, AnyParentNode, RepeatRange } from '../hierarchy.ts';
20
+ import type { AnyChildNode, AnyNode, RepeatRange } from '../hierarchy.ts';
20
21
  import type { EvaluationContext } from '../internal-api/EvaluationContext.ts';
21
22
  import type { RepeatInstance } from '../repeat/RepeatInstance.ts';
22
23
  import type { Root } from '../Root.ts';
@@ -63,7 +64,7 @@ export abstract class DescendantNode<
63
64
  Definition extends DescendantNodeDefinition,
64
65
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
66
  Spec extends DescendantNodeStateSpec<any>,
66
- Parent extends AnyParentNode,
67
+ Parent extends AnyNode,
67
68
  Child extends AnyChildNode | null = null,
68
69
  >
69
70
  extends InstanceNode<Definition, Spec, Parent, Child>
@@ -137,7 +138,7 @@ export abstract class DescendantNode<
137
138
 
138
139
  constructor(
139
140
  override readonly parent: Parent,
140
- override readonly instanceNode: StaticElement | null,
141
+ override readonly instanceNode: StaticAttribute | StaticElement | null,
141
142
  override readonly definition: Definition,
142
143
  options?: DescendantNodeOptions
143
144
  ) {
@@ -167,11 +168,6 @@ export abstract class DescendantNode<
167
168
  return true;
168
169
  }
169
170
  }
170
- for (const attr of parent.getAttributes()) {
171
- if (attr === self) {
172
- return true;
173
- }
174
- }
175
171
  return false;
176
172
  });
177
173
  });
@@ -28,7 +28,7 @@ import type { AnyNodeDefinition } from '../../parse/model/NodeDefinition.ts';
28
28
  import type { Attribute } from '../Attribute.ts';
29
29
  import type { PrimaryInstance } from '../PrimaryInstance.ts';
30
30
  import type { Root } from '../Root.ts';
31
- import type { AnyChildNode, AnyNode, AnyParentNode } from '../hierarchy.ts';
31
+ import type { AnyChildNode, AnyNode } from '../hierarchy.ts';
32
32
  import { nodeID } from '../identity.ts';
33
33
  import type { EvaluationContext } from '../internal-api/EvaluationContext.ts';
34
34
  import type { InstanceConfig } from '../internal-api/InstanceConfig.ts';
@@ -84,7 +84,7 @@ export type InstanceNodeCurrentState<
84
84
  };
85
85
 
86
86
  interface ComputableReferenceNode {
87
- readonly parent: AnyParentNode | null;
87
+ readonly parent: AnyNode | null;
88
88
  readonly definition: AnyNodeDefinition;
89
89
  }
90
90
 
@@ -103,7 +103,7 @@ export abstract class InstanceNode<
103
103
  Definition extends AnyNodeDefinition,
104
104
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
105
  Spec extends InstanceNodeStateSpec<any>,
106
- Parent extends AnyParentNode | null,
106
+ Parent extends AnyNode | null,
107
107
  Child extends AnyChildNode | null = null,
108
108
  >
109
109
  implements BaseEngineNode, XFormsXPathPrimaryInstanceNode, EvaluationContext
@@ -240,13 +240,13 @@ export abstract class InstanceNode<
240
240
  * (though for those nodes it will always be empty). This affords consistency
241
241
  * and efficiency of interface for those internal uses.
242
242
  */
243
- abstract getChildren(this: AnyInstanceNode): ReadonlyArray<Exclude<AnyChildNode, Attribute>>;
243
+ abstract getChildren(this: AnyInstanceNode): readonly AnyChildNode[];
244
244
 
245
245
  // XFormsXPathNode
246
246
  /**
247
247
  * @todo Values as text nodes(?)
248
248
  */
249
- getXPathChildNodes(): ReadonlyArray<Exclude<AnyChildNode, Attribute>> {
249
+ getXPathChildNodes(): readonly AnyChildNode[] {
250
250
  return (this as AnyInstanceNode).getChildren().flatMap((child) => {
251
251
  switch (child.nodeType) {
252
252
  case 'repeat-range:controlled':
@@ -272,4 +272,6 @@ export abstract class InstanceNode<
272
272
  .map((child) => child.getXPathValue())
273
273
  .join('');
274
274
  }
275
+
276
+ abstract getAttributes(): readonly Attribute[];
275
277
  }
@@ -21,6 +21,7 @@ import type { SimpleAtomicState } from '../../lib/reactivity/types.ts';
21
21
  import type { SharedValidationState } from '../../lib/reactivity/validation/createValidation.ts';
22
22
  import { createValidationState } from '../../lib/reactivity/validation/createValidation.ts';
23
23
  import { LeafNodeDefinition } from '../../parse/model/LeafNodeDefinition.ts';
24
+ import type { Attribute } from '../Attribute.ts';
24
25
  import type { GeneralParentNode } from '../hierarchy.ts';
25
26
  import type { EvaluationContext } from '../internal-api/EvaluationContext.ts';
26
27
  import type {
@@ -36,7 +37,7 @@ export type ValueNodeDefinition<V extends ValueType> = LeafNodeDefinition<V>;
36
37
 
37
38
  export interface ValueNodeStateSpec<RuntimeValue> extends DescendantNodeStateSpec<RuntimeValue> {
38
39
  readonly children: null;
39
- readonly attributes: null;
40
+ readonly attributes: Accessor<readonly Attribute[]>;
40
41
  readonly value: SimpleAtomicState<RuntimeValue>;
41
42
  readonly instanceValue: Accessor<string>;
42
43
  }
@@ -1,8 +1,19 @@
1
1
  import { Attribute } from '../Attribute';
2
- import type { AnyParentNode } from '../hierarchy';
2
+ import type { AnyNode } from '../hierarchy.ts';
3
+ import type { InputControl } from '../InputControl.ts';
4
+ import type { ModelValue } from '../ModelValue.ts';
5
+ import type { Note } from '../Note.ts';
6
+ import type { RangeControl } from '../RangeControl.ts';
3
7
 
4
- export function buildAttributes(parent: AnyParentNode): Attribute[] {
5
- return Array.from(parent.definition.attributes.values()).map((attributeDefinition) => {
6
- return new Attribute(parent, attributeDefinition, attributeDefinition.template);
8
+ export function buildAttributes(
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ owner: AnyNode | InputControl<any> | ModelValue<any> | Note<any> | RangeControl<any>
11
+ ): Attribute[] {
12
+ const attributes = owner.definition.attributes;
13
+ if (!attributes) {
14
+ return [];
15
+ }
16
+ return Array.from(attributes.values()).map((attributeDefinition) => {
17
+ return new Attribute(owner, attributeDefinition, attributeDefinition.template);
7
18
  });
8
19
  }
@@ -1,3 +1,4 @@
1
+ import type { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
1
2
  import type { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
2
3
  import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
3
4
  import type { ModelDefinition } from '../../parse/model/ModelDefinition.ts';
@@ -37,7 +38,7 @@ const collectModelChildNodesets = (parentTemplate: StaticElement): readonly stri
37
38
  type InstanceNodesByNodeset = ReadonlyMap<string, readonly [StaticElement, ...StaticElement[]]>;
38
39
 
39
40
  const groupChildElementsByNodeset = (
40
- parent: StaticDocument | StaticElement
41
+ parent: StaticAttribute | StaticDocument | StaticElement
41
42
  ): InstanceNodesByNodeset => {
42
43
  const result = new Map<string, [StaticElement, ...StaticElement[]]>();
43
44
 
@@ -217,7 +217,7 @@ const buildDeprecatedIDDefinition = (
217
217
  const nodeset = instanceNode.nodeset;
218
218
  const bind = group.model.binds.getOrCreateBindDefinition(nodeset);
219
219
 
220
- return new LeafNodeDefinition(group.parent.definition, bind, null, instanceNode);
220
+ return new LeafNodeDefinition(group.model, group.parent.definition, bind, null, instanceNode);
221
221
  };
222
222
 
223
223
  const buildDeprecatedID = (
@@ -24,6 +24,7 @@ export type AnyNode =
24
24
  | Group
25
25
  | RepeatRange
26
26
  | RepeatInstance
27
+ | Attribute
27
28
  | AnyNote
28
29
  | AnyModelValue
29
30
  | AnyInputControl
@@ -63,8 +64,7 @@ export type AnyChildNode =
63
64
  | RankControl
64
65
  | SelectControl
65
66
  | TriggerControl
66
- | UploadControl
67
- | Attribute;
67
+ | UploadControl;
68
68
 
69
69
  // prettier-ignore
70
70
  export type GeneralChildNode =
@@ -1,12 +1,16 @@
1
+ import type { Accessor } from 'solid-js';
1
2
  import type { FormInstanceInitializationMode } from '../../client/index.ts';
2
3
  import type { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
3
4
  import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
4
5
  import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
5
6
  import type { AnyBindPreloadDefinition } from '../../parse/model/BindPreloadDefinition.ts';
7
+ import type { ModelDefinition } from '../../parse/model/ModelDefinition.ts';
6
8
  import type { EvaluationContext } from './EvaluationContext.ts';
9
+ import type { InstanceConfig } from './InstanceConfig.ts';
7
10
 
8
11
  export interface InstanceAttributeContextDocument {
9
12
  readonly initializationMode: FormInstanceInitializationMode;
13
+ readonly isAttached: Accessor<boolean>;
10
14
  }
11
15
 
12
16
  export type DecodeInstanceValue = (value: string) => string;
@@ -20,6 +24,7 @@ interface InstanceAttributeContextDefinitionBind {
20
24
  export interface InstanceAttributeContextDefinition {
21
25
  readonly bind: InstanceAttributeContextDefinitionBind;
22
26
  readonly template: StaticAttribute;
27
+ readonly model: ModelDefinition;
23
28
  }
24
29
 
25
30
  export interface AttributeContext extends EvaluationContext {
@@ -27,6 +32,7 @@ export interface AttributeContext extends EvaluationContext {
27
32
  readonly rootDocument: InstanceAttributeContextDocument;
28
33
  readonly definition: InstanceAttributeContextDefinition;
29
34
  readonly instanceNode: StaticAttribute;
35
+ readonly instanceConfig: InstanceConfig;
30
36
  readonly decodeInstanceValue: DecodeInstanceValue;
31
37
 
32
38
  isReadonly(): boolean;
@@ -1,5 +1,8 @@
1
1
  import type { InstanceAttachmentFileNameFactory } from '../../client/attachments/InstanceAttachmentsConfig.ts';
2
- import type { FormInstanceConfig } from '../../client/form/FormInstanceConfig.ts';
2
+ import type {
3
+ FormInstanceConfig,
4
+ PreloadProperties,
5
+ } from '../../client/form/FormInstanceConfig.ts';
3
6
  import type { OpaqueReactiveObjectFactory } from '../../client/OpaqueReactiveObjectFactory.ts';
4
7
 
5
8
  export interface InstanceConfig {
@@ -9,4 +12,6 @@ export interface InstanceConfig {
9
12
  readonly clientStateFactory: OpaqueReactiveObjectFactory;
10
13
 
11
14
  readonly computeAttachmentName: InstanceAttachmentFileNameFactory;
15
+
16
+ readonly preloadProperties: PreloadProperties;
12
17
  }
@@ -1,12 +1,16 @@
1
+ import type { Accessor } from 'solid-js';
1
2
  import type { FormInstanceInitializationMode } from '../../client/index.ts';
2
3
  import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
3
4
  import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
4
5
  import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
5
6
  import type { AnyBindPreloadDefinition } from '../../parse/model/BindPreloadDefinition.ts';
7
+ import type { ModelDefinition } from '../../parse/model/ModelDefinition.ts';
6
8
  import type { EvaluationContext } from './EvaluationContext.ts';
9
+ import type { InstanceConfig } from './InstanceConfig.ts';
7
10
 
8
11
  export interface InstanceValueContextDocument {
9
12
  readonly initializationMode: FormInstanceInitializationMode;
13
+ readonly isAttached: Accessor<boolean>;
10
14
  }
11
15
 
12
16
  export type DecodeInstanceValue = (value: string) => string;
@@ -20,6 +24,7 @@ interface InstanceValueContextDefinitionBind {
20
24
  export interface InstanceValueContextDefinition {
21
25
  readonly bind: InstanceValueContextDefinitionBind;
22
26
  readonly template: StaticLeafElement;
27
+ readonly model: ModelDefinition;
23
28
  }
24
29
 
25
30
  export interface InstanceValueContext extends EvaluationContext {
@@ -27,6 +32,7 @@ export interface InstanceValueContext extends EvaluationContext {
27
32
  readonly rootDocument: InstanceValueContextDocument;
28
33
  readonly definition: InstanceValueContextDefinition;
29
34
  readonly instanceNode: StaticLeafElement | null;
35
+ readonly instanceConfig: InstanceConfig;
30
36
  readonly decodeInstanceValue: DecodeInstanceValue;
31
37
 
32
38
  isReadonly(): boolean;
@@ -4,7 +4,6 @@ import type { QualifiedName } from '../../../lib/names/QualifiedName.ts';
4
4
  export type SerializedInstanceValue = string;
5
5
 
6
6
  interface ClientReactiveSerializableAttributeNodeCurrentState {
7
- get relevant(): boolean;
8
7
  get instanceValue(): SerializedInstanceValue;
9
8
  }
10
9