@getodk/xforms-engine 0.14.0 → 0.15.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 (87) hide show
  1. package/dist/client/AttributeNode.d.ts +53 -0
  2. package/dist/client/index.d.ts +1 -0
  3. package/dist/client/node-types.d.ts +1 -1
  4. package/dist/client/validation.d.ts +7 -1
  5. package/dist/index.js +436 -164
  6. package/dist/index.js.map +1 -1
  7. package/dist/instance/Attribute.d.ts +58 -0
  8. package/dist/instance/Group.d.ts +4 -0
  9. package/dist/instance/PrimaryInstance.d.ts +4 -0
  10. package/dist/instance/Root.d.ts +4 -0
  11. package/dist/instance/UploadControl.d.ts +4 -0
  12. package/dist/instance/abstract/InstanceNode.d.ts +7 -4
  13. package/dist/instance/abstract/ValueNode.d.ts +1 -0
  14. package/dist/instance/attachments/buildAttributes.d.ts +3 -0
  15. package/dist/instance/hierarchy.d.ts +2 -1
  16. package/dist/instance/internal-api/AttributeContext.d.ts +29 -0
  17. package/dist/instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.d.ts +16 -0
  18. package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +2 -0
  19. package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +2 -2
  20. package/dist/instance/repeat/BaseRepeatRange.d.ts +5 -0
  21. package/dist/instance/repeat/RepeatInstance.d.ts +4 -2
  22. package/dist/integration/xpath/adapter/XFormsXPathNode.d.ts +2 -2
  23. package/dist/lib/client-reactivity/instance-state/createAttributeNodeInstanceState.d.ts +3 -0
  24. package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +0 -3
  25. package/dist/lib/names/NamespaceDeclarationMap.d.ts +1 -1
  26. package/dist/lib/reactivity/createAttributeState.d.ts +16 -0
  27. package/dist/lib/reactivity/createAttributeValueState.d.ts +15 -0
  28. package/dist/lib/xml-serialization.d.ts +5 -9
  29. package/dist/parse/XFormDOM.d.ts +1 -1
  30. package/dist/parse/model/AttributeDefinition.d.ts +22 -0
  31. package/dist/parse/model/{RootAttributeMap.d.ts → AttributeDefinitionMap.d.ts} +4 -10
  32. package/dist/parse/model/GroupDefinition.d.ts +4 -1
  33. package/dist/parse/model/LeafNodeDefinition.d.ts +1 -0
  34. package/dist/parse/model/NodeDefinition.d.ts +8 -3
  35. package/dist/parse/model/RepeatDefinition.d.ts +4 -1
  36. package/dist/parse/model/RootDefinition.d.ts +2 -2
  37. package/dist/solid.js +436 -164
  38. package/dist/solid.js.map +1 -1
  39. package/package.json +5 -5
  40. package/src/client/AttributeNode.ts +62 -0
  41. package/src/client/index.ts +1 -0
  42. package/src/client/node-types.ts +1 -0
  43. package/src/client/validation.ts +9 -1
  44. package/src/instance/Attribute.ts +164 -0
  45. package/src/instance/Group.ts +16 -0
  46. package/src/instance/InputControl.ts +1 -0
  47. package/src/instance/ModelValue.ts +1 -0
  48. package/src/instance/Note.ts +1 -0
  49. package/src/instance/PrimaryInstance.ts +17 -0
  50. package/src/instance/RangeControl.ts +1 -0
  51. package/src/instance/RankControl.ts +1 -0
  52. package/src/instance/Root.ts +16 -0
  53. package/src/instance/SelectControl.ts +1 -0
  54. package/src/instance/TriggerControl.ts +1 -0
  55. package/src/instance/UploadControl.ts +14 -0
  56. package/src/instance/abstract/DescendantNode.ts +5 -1
  57. package/src/instance/abstract/InstanceNode.ts +6 -3
  58. package/src/instance/abstract/ValueNode.ts +1 -0
  59. package/src/instance/attachments/buildAttributes.ts +8 -0
  60. package/src/instance/hierarchy.ts +3 -1
  61. package/src/instance/internal-api/AttributeContext.ts +34 -0
  62. package/src/instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.ts +19 -0
  63. package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +2 -0
  64. package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +2 -3
  65. package/src/instance/repeat/BaseRepeatRange.ts +14 -0
  66. package/src/instance/repeat/RepeatInstance.ts +14 -5
  67. package/src/integration/xpath/adapter/XFormsXPathNode.ts +3 -1
  68. package/src/lib/client-reactivity/instance-state/createAttributeNodeInstanceState.ts +16 -0
  69. package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +5 -5
  70. package/src/lib/client-reactivity/instance-state/createRootInstanceState.ts +6 -9
  71. package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +5 -15
  72. package/src/lib/names/NamespaceDeclarationMap.ts +1 -1
  73. package/src/lib/reactivity/createAttributeState.ts +51 -0
  74. package/src/lib/reactivity/createAttributeValueState.ts +189 -0
  75. package/src/lib/xml-serialization.ts +30 -34
  76. package/src/parse/model/AttributeDefinition.ts +58 -0
  77. package/src/parse/model/{RootAttributeMap.ts → AttributeDefinitionMap.ts} +7 -13
  78. package/src/parse/model/GroupDefinition.ts +6 -0
  79. package/src/parse/model/LeafNodeDefinition.ts +1 -0
  80. package/src/parse/model/NodeDefinition.ts +11 -3
  81. package/src/parse/model/RepeatDefinition.ts +8 -1
  82. package/src/parse/model/RootDefinition.ts +5 -5
  83. package/src/parse/model/nodeDefinitionMap.ts +1 -1
  84. package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +0 -22
  85. package/dist/parse/model/RootAttributeDefinition.d.ts +0 -21
  86. package/src/error/TemplatedNodeAttributeSerializationError.ts +0 -24
  87. package/src/parse/model/RootAttributeDefinition.ts +0 -44
@@ -0,0 +1,58 @@
1
+ import { XPathNodeKindKey } from '@getodk/xpath';
2
+ import { Accessor } from 'solid-js';
3
+ import { AttributeNode } from '../client/AttributeNode.ts';
4
+ import { ActiveLanguage, InstanceState, NullValidationState } from '../client/index.ts';
5
+ import { XFormsXPathAttribute } from '../integration/xpath/adapter/XFormsXPathNode.ts';
6
+ import { EngineXPathEvaluator } from '../integration/xpath/EngineXPathEvaluator.ts';
7
+ import { StaticAttribute } from '../integration/xpath/static-dom/StaticAttribute.ts';
8
+ import { RuntimeInputValue, RuntimeValue } from '../lib/codecs/getSharedValueCodec.ts';
9
+ import { RuntimeValueSetter, RuntimeValueState } from '../lib/codecs/ValueCodec.ts';
10
+ import { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
11
+ import { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
12
+ import { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
13
+ import { SimpleAtomicState } from '../lib/reactivity/types.ts';
14
+ import { AttributeDefinition } from '../parse/model/AttributeDefinition.ts';
15
+ import { DescendantNodeSharedStateSpec } from './abstract/DescendantNode.ts';
16
+ import { InstanceNode } from './abstract/InstanceNode.ts';
17
+ import { AnyParentNode } from './hierarchy.ts';
18
+ import { AttributeContext } from './internal-api/AttributeContext.ts';
19
+ import { DecodeInstanceValue } from './internal-api/InstanceValueContext.ts';
20
+ import { ClientReactiveSerializableAttributeNode } from './internal-api/serialization/ClientReactiveSerializableAttributeNode.ts';
21
+ import { Root } from './Root.ts';
22
+ export interface AttributeStateSpec extends DescendantNodeSharedStateSpec {
23
+ readonly children: null;
24
+ readonly attributes: null;
25
+ readonly value: SimpleAtomicState<string>;
26
+ readonly instanceValue: Accessor<string>;
27
+ readonly label: null;
28
+ readonly hint: null;
29
+ readonly valueOptions: null;
30
+ }
31
+ export declare class Attribute extends InstanceNode<AttributeDefinition, AttributeStateSpec, AnyParentNode, null> implements AttributeNode, ClientReactiveSerializableAttributeNode, AttributeContext, XFormsXPathAttribute {
32
+ readonly instanceNode: StaticAttribute;
33
+ readonly [XPathNodeKindKey] = "attribute";
34
+ protected readonly state: SharedNodeState<AttributeStateSpec>;
35
+ protected readonly engineState: EngineState<AttributeStateSpec>;
36
+ readonly validationState: NullValidationState;
37
+ readonly nodeType = "attribute";
38
+ readonly currentState: CurrentState<AttributeStateSpec>;
39
+ readonly instanceState: InstanceState;
40
+ readonly appearances: null;
41
+ readonly nodeOptions: null;
42
+ readonly valueType: string;
43
+ readonly decodeInstanceValue: DecodeInstanceValue;
44
+ protected readonly getInstanceValue: Accessor<string>;
45
+ protected readonly valueState: RuntimeValueState<RuntimeValue<'string'>>;
46
+ protected readonly setValueState: RuntimeValueSetter<RuntimeInputValue<'string'>>;
47
+ readonly evaluator: EngineXPathEvaluator;
48
+ readonly getActiveLanguage: Accessor<ActiveLanguage>;
49
+ readonly root: Root;
50
+ readonly isRelevant: Accessor<boolean>;
51
+ readonly isAttached: Accessor<boolean>;
52
+ readonly isReadonly: Accessor<boolean>;
53
+ readonly hasReadonlyAncestor: Accessor<boolean>;
54
+ readonly hasNonRelevantAncestor: Accessor<boolean>;
55
+ constructor(parent: AnyParentNode, definition: AttributeDefinition, instanceNode: StaticAttribute);
56
+ setValue(value: string): Root;
57
+ getChildren(): readonly [];
58
+ }
@@ -12,6 +12,7 @@ import { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts
12
12
  import { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
13
13
  import { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
14
14
  import { DescendantNodeSharedStateSpec, DescendantNode } from './abstract/DescendantNode.ts';
15
+ import { Attribute } from './Attribute.ts';
15
16
  import { GeneralChildNode, GeneralParentNode } from './hierarchy.ts';
16
17
  import { EvaluationContext } from './internal-api/EvaluationContext.ts';
17
18
  import { ClientReactiveSerializableParentNode } from './internal-api/serialization/ClientReactiveSerializableParentNode.ts';
@@ -19,11 +20,13 @@ interface GroupStateSpec extends DescendantNodeSharedStateSpec {
19
20
  readonly label: Accessor<TextRange<'label'> | null>;
20
21
  readonly hint: null;
21
22
  readonly children: Accessor<readonly FormNodeID[]>;
23
+ readonly attributes: Accessor<readonly Attribute[]>;
22
24
  readonly valueOptions: null;
23
25
  readonly value: null;
24
26
  }
25
27
  export declare class Group extends DescendantNode<GroupDefinition, GroupStateSpec, GeneralParentNode, GeneralChildNode> implements GroupNode, XFormsXPathElement, EvaluationContext, ClientReactiveSerializableParentNode<GeneralChildNode> {
26
28
  private readonly childrenState;
29
+ private readonly attributeState;
27
30
  readonly [XPathNodeKindKey] = "element";
28
31
  protected readonly state: SharedNodeState<GroupStateSpec>;
29
32
  protected engineState: EngineState<GroupStateSpec>;
@@ -35,5 +38,6 @@ export declare class Group extends DescendantNode<GroupDefinition, GroupStateSpe
35
38
  readonly instanceState: InstanceState;
36
39
  constructor(parent: GeneralParentNode, instanceNode: StaticElement | null, definition: GroupDefinition);
37
40
  getChildren(): readonly GeneralChildNode[];
41
+ getAttributes(): readonly Attribute[];
38
42
  }
39
43
  export {};
@@ -21,6 +21,7 @@ import { RootDefinition } from '../parse/model/RootDefinition.ts';
21
21
  import { SecondaryInstancesDefinition } from '../parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts';
22
22
  import { InstanceNode } from './abstract/InstanceNode.ts';
23
23
  import { InstanceAttachmentsState } from './attachments/InstanceAttachmentsState.ts';
24
+ import { Attribute } from './Attribute.ts';
24
25
  import { InitialInstanceState } from './input/InitialInstanceState.ts';
25
26
  import { EvaluationContext } from './internal-api/EvaluationContext.ts';
26
27
  import { InstanceConfig } from './internal-api/InstanceConfig.ts';
@@ -36,6 +37,7 @@ interface PrimaryInstanceStateSpec {
36
37
  readonly label: null;
37
38
  readonly hint: null;
38
39
  readonly children: Accessor<readonly FormNodeID[]>;
40
+ readonly attributes: Accessor<readonly Attribute[]>;
39
41
  readonly valueOptions: null;
40
42
  readonly value: null;
41
43
  readonly activeLanguage: Accessor<ActiveLanguage>;
@@ -85,6 +87,7 @@ export declare class PrimaryInstance<Mode extends FormInstanceInitializationMode
85
87
  readonly isAttached: Accessor<boolean>;
86
88
  readonly evaluator: EngineXPathEvaluator;
87
89
  readonly contextNode: this;
90
+ private readonly attributeState;
88
91
  constructor(options: PrimaryInstanceOptions<Mode>);
89
92
  /**
90
93
  * @todo Note that this method's signature is intentionally derived from
@@ -107,5 +110,6 @@ export declare class PrimaryInstance<Mode extends FormInstanceInitializationMode
107
110
  */
108
111
  setLanguage(language: FormLanguage): FormLanguage;
109
112
  prepareInstancePayload<PayloadType extends InstancePayloadType = 'monolithic'>(options?: InstancePayloadOptions<PayloadType>): Promise<InstancePayload<PayloadType>>;
113
+ getAttributes(): readonly Attribute[];
110
114
  }
111
115
  export {};
@@ -15,6 +15,7 @@ import { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeSt
15
15
  import { BodyClassList } from '../parse/body/BodyDefinition.ts';
16
16
  import { RootDefinition } from '../parse/model/RootDefinition.ts';
17
17
  import { DescendantNode } from './abstract/DescendantNode.ts';
18
+ import { Attribute } from './Attribute.ts';
18
19
  import { GeneralChildNode } from './hierarchy.ts';
19
20
  import { EvaluationContext } from './internal-api/EvaluationContext.ts';
20
21
  import { ClientReactiveSerializableParentNode } from './internal-api/serialization/ClientReactiveSerializableParentNode.ts';
@@ -28,12 +29,14 @@ interface RootStateSpec {
28
29
  readonly label: null;
29
30
  readonly hint: null;
30
31
  readonly children: Accessor<readonly FormNodeID[]>;
32
+ readonly attributes: Accessor<readonly Attribute[]>;
31
33
  readonly valueOptions: null;
32
34
  readonly value: null;
33
35
  readonly activeLanguage: Accessor<ActiveLanguage>;
34
36
  }
35
37
  export declare class Root extends DescendantNode<RootDefinition, RootStateSpec, PrimaryInstance, GeneralChildNode> implements RootNode, XFormsXPathElement, EvaluationContext, TranslationContext, ClientReactiveSerializableParentNode<GeneralChildNode> {
36
38
  private readonly childrenState;
39
+ private readonly attributeState;
37
40
  readonly [XPathNodeKindKey] = "element";
38
41
  protected readonly state: SharedNodeState<RootStateSpec>;
39
42
  protected readonly engineState: EngineState<RootStateSpec>;
@@ -54,6 +57,7 @@ export declare class Root extends DescendantNode<RootDefinition, RootStateSpec,
54
57
  readonly languages: FormLanguages;
55
58
  constructor(parent: PrimaryInstance);
56
59
  getChildren(): readonly GeneralChildNode[];
60
+ getAttributes(): readonly Attribute[];
57
61
  setLanguage(language: FormLanguage): Root;
58
62
  prepareInstancePayload<PayloadType extends InstancePayloadType = 'monolithic'>(options?: InstancePayloadOptions<PayloadType>): Promise<InstancePayload<PayloadType>>;
59
63
  }
@@ -12,6 +12,7 @@ import { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
12
12
  import { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
13
13
  import { SimpleAtomicState } from '../lib/reactivity/types.ts';
14
14
  import { UnknownAppearanceDefinition } from '../parse/body/appearance/unknownAppearanceParser.ts';
15
+ import { Attribute } from './Attribute.ts';
15
16
  import { Root } from './Root.ts';
16
17
  import { DescendantNodeStateSpec, DescendantNode } from './abstract/DescendantNode.ts';
17
18
  import { InstanceAttachmentRuntimeValue } from './attachments/InstanceAttachment.ts';
@@ -28,6 +29,7 @@ interface UploadControlStateSpec extends DescendantNodeStateSpec<InstanceAttachm
28
29
  readonly label: Accessor<TextRange<'label'> | null>;
29
30
  readonly hint: Accessor<TextRange<'hint'> | null>;
30
31
  readonly children: null;
32
+ readonly attributes: Accessor<readonly Attribute[]>;
31
33
  readonly valueOptions: null;
32
34
  readonly value: SimpleAtomicState<InstanceAttachmentRuntimeValue>;
33
35
  readonly instanceValue: Accessor<InstanceAttachmentFileName>;
@@ -37,6 +39,7 @@ export declare class UploadControl extends DescendantNode<UploadDefinition<'bina
37
39
  static from(parent: GeneralParentNode, instanceNode: StaticLeafElement | null, definition: UploadDefinition): UploadControl;
38
40
  private readonly validation;
39
41
  private readonly instanceAttachment;
42
+ private readonly attributeState;
40
43
  readonly [XPathNodeKindKey] = "element";
41
44
  readonly getXPathValue: () => InstanceAttachmentFileName;
42
45
  protected readonly state: SharedNodeState<UploadControlStateSpec>;
@@ -54,5 +57,6 @@ export declare class UploadControl extends DescendantNode<UploadDefinition<'bina
54
57
  isBlank(): boolean;
55
58
  getChildren(): readonly [];
56
59
  setValue(value: InstanceAttachmentRuntimeValue): Root;
60
+ getAttributes(): readonly Attribute[];
57
61
  }
58
62
  export {};
@@ -10,6 +10,7 @@ import { ActiveLanguage, TextRange } from '../../index.ts';
10
10
  import { EngineXPathEvaluator } from '../../integration/xpath/EngineXPathEvaluator.ts';
11
11
  import { XFormsXPathPrimaryInstanceNode, XFormsXPathPrimaryInstanceNodeKind } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
12
12
  import { PrimaryInstanceXPathNode } from '../../integration/xpath/adapter/kind.ts';
13
+ import { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
13
14
  import { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
14
15
  import { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
15
16
  import { CurrentState } from '../../lib/reactivity/node-state/createCurrentState.ts';
@@ -18,6 +19,7 @@ import { SharedNodeState } from '../../lib/reactivity/node-state/createSharedNod
18
19
  import { ReactiveScope } from '../../lib/reactivity/scope.ts';
19
20
  import { SimpleAtomicState } from '../../lib/reactivity/types.ts';
20
21
  import { AnyNodeDefinition } from '../../parse/model/NodeDefinition.ts';
22
+ import { Attribute } from '../Attribute.ts';
21
23
  import { PrimaryInstance } from '../PrimaryInstance.ts';
22
24
  import { Root } from '../Root.ts';
23
25
  import { AnyChildNode, AnyParentNode } from '../hierarchy.ts';
@@ -36,6 +38,7 @@ export interface InstanceNodeStateSpec<Value = never> {
36
38
  readonly label: Accessor<TextRange<'label'> | null> | null;
37
39
  readonly hint: Accessor<TextRange<'hint'> | null> | null;
38
40
  readonly children: Accessor<readonly FormNodeID[]> | null;
41
+ readonly attributes: Accessor<readonly Attribute[]> | null;
39
42
  readonly valueOptions: InstanceNodeValueOptionsStateSpec;
40
43
  readonly value: Signal<Value> | SimpleAtomicState<Value> | null;
41
44
  }
@@ -59,7 +62,7 @@ export interface InstanceNodeOptions {
59
62
  export declare abstract class InstanceNode<Definition extends AnyNodeDefinition, Spec extends InstanceNodeStateSpec<any>, Parent extends AnyParentNode | null, Child extends AnyChildNode | null = null> implements BaseEngineNode, XFormsXPathPrimaryInstanceNode, EvaluationContext {
60
63
  readonly instanceConfig: InstanceConfig;
61
64
  readonly parent: Parent;
62
- readonly instanceNode: StaticDocument | StaticElement | null;
65
+ readonly instanceNode: StaticAttribute | StaticDocument | StaticElement | null;
63
66
  readonly definition: Definition;
64
67
  protected abstract readonly state: SharedNodeState<Spec>;
65
68
  protected abstract readonly engineState: EngineState<Spec>;
@@ -106,7 +109,7 @@ export declare abstract class InstanceNode<Definition extends AnyNodeDefinition,
106
109
  * constrain) their more specific `this` type.
107
110
  */
108
111
  readonly contextNode: PrimaryInstanceXPathNode;
109
- constructor(instanceConfig: InstanceConfig, parent: Parent, instanceNode: StaticDocument | StaticElement | null, definition: Definition, options?: InstanceNodeOptions);
112
+ constructor(instanceConfig: InstanceConfig, parent: Parent, instanceNode: StaticAttribute | StaticDocument | StaticElement | null, definition: Definition, options?: InstanceNodeOptions);
110
113
  /** @package */
111
114
  isPrimaryInstance(): this is PrimaryInstance;
112
115
  /** @package */
@@ -121,11 +124,11 @@ export declare abstract class InstanceNode<Definition extends AnyNodeDefinition,
121
124
  * (though for those nodes it will always be empty). This affords consistency
122
125
  * and efficiency of interface for those internal uses.
123
126
  */
124
- abstract getChildren(this: AnyInstanceNode): readonly AnyChildNode[];
127
+ abstract getChildren(this: AnyInstanceNode): ReadonlyArray<Exclude<AnyChildNode, Attribute>>;
125
128
  /**
126
129
  * @todo Values as text nodes(?)
127
130
  */
128
- getXPathChildNodes(): readonly AnyChildNode[];
131
+ getXPathChildNodes(): ReadonlyArray<Exclude<AnyChildNode, Attribute>>;
129
132
  getXPathValue(): string;
130
133
  }
131
134
  export {};
@@ -23,6 +23,7 @@ import { DescendantNodeStateSpec, DescendantNode } from './DescendantNode.ts';
23
23
  export type ValueNodeDefinition<V extends ValueType> = LeafNodeDefinition<V>;
24
24
  export interface ValueNodeStateSpec<RuntimeValue> extends DescendantNodeStateSpec<RuntimeValue> {
25
25
  readonly children: null;
26
+ readonly attributes: null;
26
27
  readonly value: SimpleAtomicState<RuntimeValue>;
27
28
  readonly instanceValue: Accessor<string>;
28
29
  }
@@ -0,0 +1,3 @@
1
+ import { Attribute } from '../Attribute';
2
+ import { AnyParentNode } from '../hierarchy';
3
+ export declare function buildAttributes(parent: AnyParentNode): Attribute[];
@@ -1,3 +1,4 @@
1
+ import { Attribute } from './Attribute.ts';
1
2
  import { Group } from './Group.ts';
2
3
  import { AnyInputControl } from './InputControl.ts';
3
4
  import { AnyModelValue } from './ModelValue.ts';
@@ -16,6 +17,6 @@ export type RepeatRange = RepeatRangeControlled | RepeatRangeUncontrolled;
16
17
  export type AnyNode = PrimaryInstance | Root | Group | RepeatRange | RepeatInstance | AnyNote | AnyModelValue | AnyInputControl | AnyRangeControl | RankControl | SelectControl | TriggerControl | UploadControl;
17
18
  export type AnyParentNode = PrimaryInstance | Root | Group | RepeatRange | RepeatInstance;
18
19
  export type GeneralParentNode = Root | Group | RepeatInstance;
19
- export type AnyChildNode = Root | Group | RepeatRange | RepeatInstance | AnyModelValue | AnyNote | AnyInputControl | AnyRangeControl | RankControl | SelectControl | TriggerControl | UploadControl;
20
+ export type AnyChildNode = Root | Group | RepeatRange | RepeatInstance | AnyModelValue | AnyNote | AnyInputControl | AnyRangeControl | RankControl | SelectControl | TriggerControl | UploadControl | Attribute;
20
21
  export type GeneralChildNode = Group | RepeatRange | AnyModelValue | AnyNote | AnyInputControl | AnyRangeControl | RankControl | SelectControl | TriggerControl | UploadControl;
21
22
  export type AnyValueNode = AnyModelValue | AnyNote | AnyInputControl | AnyRangeControl | RankControl | SelectControl | TriggerControl | UploadControl;
@@ -0,0 +1,29 @@
1
+ import { FormInstanceInitializationMode } from '../../client/index.ts';
2
+ import { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
3
+ import { ReactiveScope } from '../../lib/reactivity/scope.ts';
4
+ import { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
5
+ import { AnyBindPreloadDefinition } from '../../parse/model/BindPreloadDefinition.ts';
6
+ import { EvaluationContext } from './EvaluationContext.ts';
7
+ export interface InstanceAttributeContextDocument {
8
+ readonly initializationMode: FormInstanceInitializationMode;
9
+ }
10
+ export type DecodeInstanceValue = (value: string) => string;
11
+ interface InstanceAttributeContextDefinitionBind {
12
+ readonly preload: AnyBindPreloadDefinition | null;
13
+ readonly calculate: BindComputationExpression<'calculate'> | null;
14
+ readonly readonly: BindComputationExpression<'readonly'>;
15
+ }
16
+ export interface InstanceAttributeContextDefinition {
17
+ readonly bind: InstanceAttributeContextDefinitionBind;
18
+ readonly template: StaticAttribute;
19
+ }
20
+ export interface AttributeContext extends EvaluationContext {
21
+ readonly scope: ReactiveScope;
22
+ readonly rootDocument: InstanceAttributeContextDocument;
23
+ readonly definition: InstanceAttributeContextDefinition;
24
+ readonly instanceNode: StaticAttribute;
25
+ readonly decodeInstanceValue: DecodeInstanceValue;
26
+ isReadonly(): boolean;
27
+ isRelevant(): boolean;
28
+ }
29
+ export {};
@@ -0,0 +1,16 @@
1
+ import { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
+ import { QualifiedName } from '../../../lib/names/QualifiedName.ts';
3
+ export type SerializedInstanceValue = string;
4
+ interface ClientReactiveSerializableAttributeNodeCurrentState {
5
+ get relevant(): boolean;
6
+ get instanceValue(): SerializedInstanceValue;
7
+ }
8
+ interface ClientReactiveSerializableAttributeNodeDefinition {
9
+ readonly qualifiedName: QualifiedName;
10
+ }
11
+ export interface ClientReactiveSerializableAttributeNode {
12
+ readonly definition: ClientReactiveSerializableAttributeNodeDefinition;
13
+ readonly currentState: ClientReactiveSerializableAttributeNodeCurrentState;
14
+ readonly instanceState: InstanceState;
15
+ }
16
+ export {};
@@ -1,11 +1,13 @@
1
1
  import { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
2
  import { QualifiedName } from '../../../lib/names/QualifiedName.ts';
3
+ import { Attribute } from '../../Attribute.ts';
3
4
  export interface ClientReactiveSerializableChildNode {
4
5
  readonly instanceState: InstanceState;
5
6
  }
6
7
  export interface ClientReactiveSerializableParentNodeCurrentState<Child extends ClientReactiveSerializableChildNode> {
7
8
  get relevant(): boolean;
8
9
  get children(): readonly Child[];
10
+ get attributes(): readonly Attribute[];
9
11
  }
10
12
  export interface ClientReactiveSerializableParentNodeDefinition {
11
13
  readonly qualifiedName: QualifiedName;
@@ -1,9 +1,9 @@
1
1
  import { StaticElement } from '../../../integration/xpath/static-dom/StaticElement.ts';
2
+ import { Attribute } from '../../Attribute.ts';
2
3
  import { GeneralChildNode } from '../../hierarchy.ts';
3
4
  import { ClientReactiveSerializableParentNode, ClientReactiveSerializableParentNodeCurrentState, ClientReactiveSerializableParentNodeDefinition } from './ClientReactiveSerializableParentNode.ts';
4
5
  export interface ClientReactiveSerializableTemplatedNodeCurrentState extends ClientReactiveSerializableParentNodeCurrentState<GeneralChildNode> {
5
- /** @see {@link TemplatedNodeAttributeSerializationError} */
6
- get attributes(): unknown;
6
+ get attributes(): readonly Attribute[];
7
7
  }
8
8
  export interface ClientReactiveSerializableTemplatedNodeDefinition extends ClientReactiveSerializableParentNodeDefinition {
9
9
  readonly template: StaticElement;
@@ -9,6 +9,7 @@ import { TextRange } from '../../client/TextRange.ts';
9
9
  import { AncestorNodeValidationState } from '../../client/validation.ts';
10
10
  import { XFormsXPathNodeRange, XFormsXPathNodeRangeKind } from '../../integration/xpath/adapter/XFormsXPathNode.ts';
11
11
  import { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
12
+ import { AttributeState } from '../../lib/reactivity/createAttributeState.ts';
12
13
  import { ChildrenState } from '../../lib/reactivity/createChildrenState.ts';
13
14
  import { MaterializedChildren } from '../../lib/reactivity/materializeCurrentStateChildren.ts';
14
15
  import { CurrentState } from '../../lib/reactivity/node-state/createCurrentState.ts';
@@ -16,6 +17,7 @@ import { EngineState } from '../../lib/reactivity/node-state/createEngineState.t
16
17
  import { SharedNodeState } from '../../lib/reactivity/node-state/createSharedNodeState.ts';
17
18
  import { ControlledRepeatDefinition } from '../../parse/model/RepeatDefinition.ts';
18
19
  import { DescendantNodeSharedStateSpec, DescendantNode } from '../abstract/DescendantNode.ts';
20
+ import { Attribute } from '../Attribute.ts';
19
21
  import { GeneralParentNode } from '../hierarchy.ts';
20
22
  import { EvaluationContext } from '../internal-api/EvaluationContext.ts';
21
23
  import { ClientReactiveSerializableParentNode } from '../internal-api/serialization/ClientReactiveSerializableParentNode.ts';
@@ -24,12 +26,14 @@ interface RepeatRangeStateSpec extends DescendantNodeSharedStateSpec {
24
26
  readonly hint: null;
25
27
  readonly label: Accessor<TextRange<'label'> | null>;
26
28
  readonly children: Accessor<readonly FormNodeID[]>;
29
+ readonly attributes: Accessor<readonly Attribute[]>;
27
30
  readonly valueOptions: null;
28
31
  readonly value: null;
29
32
  }
30
33
  type BaseRepeatRangeNodeType<Definition extends AnyRepeatDefinition> = Definition extends ControlledRepeatDefinition ? 'repeat-range:controlled' : 'repeat-range:uncontrolled';
31
34
  export declare abstract class BaseRepeatRange<Definition extends AnyRepeatDefinition> extends DescendantNode<Definition, RepeatRangeStateSpec, GeneralParentNode, RepeatInstance> implements BaseRepeatRangeNode, XFormsXPathNodeRange, EvaluationContext, ClientReactiveSerializableParentNode<RepeatInstance> {
32
35
  protected readonly childrenState: ChildrenState<RepeatInstance>;
36
+ protected readonly attributeState: AttributeState;
33
37
  /**
34
38
  * A repeat range doesn't have a corresponding primary instance element of its
35
39
  * own. It is represented in the following ways:
@@ -114,5 +118,6 @@ export declare abstract class BaseRepeatRange<Definition extends AnyRepeatDefini
114
118
  protected addChildren(afterIndex: number, instanceNodes: readonly StaticElement[]): readonly RepeatInstance[];
115
119
  protected removeChildren(startIndex: number, count: number): readonly RepeatInstance[];
116
120
  getChildren(): readonly RepeatInstance[];
121
+ getAttributes(): readonly Attribute[];
117
122
  }
118
123
  export {};
@@ -12,14 +12,14 @@ import { CurrentState } from '../../lib/reactivity/node-state/createCurrentState
12
12
  import { EngineState } from '../../lib/reactivity/node-state/createEngineState.ts';
13
13
  import { SharedNodeState } from '../../lib/reactivity/node-state/createSharedNodeState.ts';
14
14
  import { DescendantNodeSharedStateSpec, DescendantNode } from '../abstract/DescendantNode.ts';
15
+ import { Attribute } from '../Attribute.ts';
15
16
  import { GeneralChildNode, RepeatRange } from '../hierarchy.ts';
16
17
  import { EvaluationContext } from '../internal-api/EvaluationContext.ts';
17
18
  import { ClientReactiveSerializableTemplatedNode } from '../internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts';
18
19
  interface RepeatInstanceStateSpec extends DescendantNodeSharedStateSpec {
19
20
  readonly label: Accessor<TextRange<'label'> | null>;
20
21
  readonly hint: null;
21
- /** @see {@link TemplatedNodeAttributeSerializationError} */
22
- readonly attributes: null;
22
+ readonly attributes: Accessor<readonly Attribute[]>;
23
23
  readonly children: Accessor<readonly FormNodeID[]>;
24
24
  readonly valueOptions: null;
25
25
  readonly value: null;
@@ -30,6 +30,7 @@ interface RepeatInstanceOptions {
30
30
  export declare class RepeatInstance extends DescendantNode<AnyRepeatDefinition, RepeatInstanceStateSpec, RepeatRange, GeneralChildNode> implements RepeatInstanceNode, XFormsXPathElement, EvaluationContext, ClientReactiveSerializableTemplatedNode {
31
31
  readonly parent: RepeatRange;
32
32
  private readonly childrenState;
33
+ private readonly attributeState;
33
34
  private readonly currentIndex;
34
35
  readonly [XPathNodeKindKey] = "element";
35
36
  protected readonly state: SharedNodeState<RepeatInstanceStateSpec>;
@@ -66,5 +67,6 @@ export declare class RepeatInstance extends DescendantNode<AnyRepeatDefinition,
66
67
  readonly instanceState: InstanceState;
67
68
  constructor(parent: RepeatRange, instanceNode: StaticElement | null, options: RepeatInstanceOptions);
68
69
  getChildren(): readonly GeneralChildNode[];
70
+ getAttributes(): readonly Attribute[];
69
71
  }
70
72
  export {};
@@ -56,11 +56,11 @@ export type XPathNamedNodeKind = XPathElementKind | XPathAttributeKind;
56
56
  export interface XFormsXPathNamedNode extends XFormsXPathNode {
57
57
  readonly [XPathNodeKindKey]: XPathNamedNodeKind;
58
58
  }
59
- export type XFormsXPathDescendantNodeKind = XFormsXPathNodeRangeKind | XPathElementKind | XPathTextKind | XPathCommentKind;
59
+ export type XFormsXPathDescendantNodeKind = XFormsXPathNodeRangeKind | XPathElementKind | XPathTextKind | XPathCommentKind | XPathAttributeKind;
60
60
  export interface XFormsXPathDescendantNode extends XFormsXPathNode {
61
61
  readonly [XPathNodeKindKey]: XFormsXPathDescendantNodeKind;
62
62
  }
63
- export type XFormsXPathPrimaryInstanceNodeKind = XPathDocumentKind | XFormsXPathNodeRangeKind | XPathElementKind | XPathTextKind;
63
+ export type XFormsXPathPrimaryInstanceNodeKind = XPathDocumentKind | XFormsXPathNodeRangeKind | XPathElementKind | XPathAttributeKind | XPathTextKind;
64
64
  export interface XFormsXPathPrimaryInstanceNode extends XFormsXPathNode {
65
65
  readonly [XPathNodeKindKey]: XFormsXPathPrimaryInstanceNodeKind;
66
66
  }
@@ -0,0 +1,3 @@
1
+ import { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
+ import { ClientReactiveSerializableAttributeNode } from '../../../instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.ts';
3
+ export declare const createAttributeNodeInstanceState: (node: ClientReactiveSerializableAttributeNode) => InstanceState;
@@ -1,6 +1,3 @@
1
1
  import { InstanceState } from '../../../client/serialization/InstanceState.ts';
2
2
  import { ClientReactiveSerializableTemplatedNode } from '../../../instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts';
3
- /**
4
- * @see {@link TemplatedNodeAttributeSerializationError}
5
- */
6
3
  export declare const createTemplatedNodeInstanceState: (node: ClientReactiveSerializableTemplatedNode) => InstanceState;
@@ -7,7 +7,7 @@ type NamedNodeDefinitionMap = ReadonlyMap<QualifiedName, NamedNodeDefinition>;
7
7
  export interface NamedSubtreeDefinition extends NamedNodeDefinition {
8
8
  readonly namespaceDeclarations: NamespaceDeclarationMap;
9
9
  readonly parent: NamedSubtreeDefinition | null;
10
- readonly attributes?: NamedNodeDefinitionMap;
10
+ readonly attributes: NamedNodeDefinitionMap | null;
11
11
  }
12
12
  /**
13
13
  * @todo This is a bit of a code style experiment! Responsive to
@@ -0,0 +1,16 @@
1
+ import { Accessor, Setter, Signal } from 'solid-js';
2
+ import { Attribute } from '../../instance/Attribute.ts';
3
+ import { ReactiveScope } from './scope.ts';
4
+ export interface AttributeState {
5
+ readonly attributes: Signal<readonly Attribute[]>;
6
+ readonly getAttributes: Accessor<readonly Attribute[]>;
7
+ readonly setAttributes: Setter<readonly Attribute[]>;
8
+ }
9
+ /**
10
+ * Creates attributes state suitable for all node types
11
+ *
12
+ * The produced {@link AttributeState.attributes} (and its get/set convenience
13
+ * methods) signal is intended to be used to store the engine's attribute state,
14
+ * and update that state when appropriate.
15
+ */
16
+ export declare const createAttributeState: (scope: ReactiveScope) => AttributeState;
@@ -0,0 +1,15 @@
1
+ import { AttributeContext } from '../../instance/internal-api/AttributeContext.ts';
2
+ import { SimpleAtomicState } from './types.ts';
3
+ export type InstanceValueState = SimpleAtomicState<string>;
4
+ /**
5
+ * Provides a consistent interface for value nodes of any type which:
6
+ *
7
+ * - derives initial state from either an existing instance (e.g. for edits) or
8
+ * the node's definition (e.g. initializing a new instance)
9
+ * - decodes current primary instance state into the value node's runtime type
10
+ * - encodes updated runtime values to store updated instance state
11
+ * - initializes reactive computation of `calculate` bind expressions for those
12
+ * nodes defined with one
13
+ * - prevents downstream writes to nodes in a readonly state
14
+ */
15
+ export declare const createAttributeValueState: (context: AttributeContext) => InstanceValueState;
@@ -1,3 +1,5 @@
1
+ import { GeneralChildNode } from '../client/hierarchy.ts';
2
+ import { Attribute } from '../instance/Attribute.ts';
1
3
  import { NamespaceDeclarationMap } from './names/NamespaceDeclarationMap.ts';
2
4
  import { QualifiedName } from './names/QualifiedName.ts';
3
5
  declare const ESCAPED_XML_TEXT_BRAND: unique symbol;
@@ -38,13 +40,7 @@ export type EscapedXMLText = string & {
38
40
  * reconsider this assumption.
39
41
  */
40
42
  export declare const escapeXMLText: <Text extends string>(text: Exclude<Text, EscapedXMLText>, attr?: boolean) => EscapedXMLText;
41
- interface SerializableElementAttribute {
42
- serializeAttributeXML(): string;
43
- }
44
- interface ElementXMLSerializationOptions {
45
- readonly namespaceDeclarations?: NamespaceDeclarationMap;
46
- readonly attributes?: readonly SerializableElementAttribute[];
47
- }
48
- export declare const serializeParentElementXML: (qualifiedName: QualifiedName, serializedChildren: readonly string[], options?: ElementXMLSerializationOptions) => string;
49
- export declare const serializeLeafElementXML: (qualifiedName: QualifiedName, xmlValue: EscapedXMLText, options?: ElementXMLSerializationOptions) => string;
43
+ export declare const serializeAttributeXML: (qualifiedName: QualifiedName, xmlValue: EscapedXMLText) => string;
44
+ export declare const serializeParentElementXML: (qualifiedName: QualifiedName, children: readonly GeneralChildNode[], attributes: readonly Attribute[], namespaceDeclarations?: NamespaceDeclarationMap) => string;
45
+ export declare const serializeLeafElementXML: (qualifiedName: QualifiedName, xmlValue: EscapedXMLText, namespaceDeclarations?: NamespaceDeclarationMap) => string;
50
46
  export {};
@@ -29,7 +29,7 @@ export declare class XFormDOM {
29
29
  readonly secondaryInstanceElements: readonly DOMSecondaryInstanceElement[];
30
30
  readonly body: Element;
31
31
  protected constructor(sourceXML: string, options: XFormDOMOptions);
32
- toJSON(): Omit<this, "head" | "html" | "title" | "toJSON" | "model" | "primaryInstance" | "primaryInstanceRoot" | "xformDocument"> & {
32
+ toJSON(): Omit<this, "head" | "html" | "title" | "toJSON" | "primaryInstance" | "model" | "primaryInstanceRoot" | "xformDocument"> & {
33
33
  xformDocument: string;
34
34
  html: string;
35
35
  head: string;
@@ -0,0 +1,22 @@
1
+ import { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
2
+ import { NamespaceDeclarationMap, NamedNodeDefinition } from '../../lib/names/NamespaceDeclarationMap.ts';
3
+ import { QualifiedName } from '../../lib/names/QualifiedName.ts';
4
+ import { BindDefinition } from './BindDefinition.ts';
5
+ import { NodeDefinition } from './NodeDefinition.ts';
6
+ import { RootDefinition } from './RootDefinition.ts';
7
+ export declare class AttributeDefinition extends NodeDefinition<'attribute'> implements NamedNodeDefinition {
8
+ readonly template: StaticAttribute;
9
+ private readonly serializedXML;
10
+ readonly value: string;
11
+ readonly type = "attribute";
12
+ readonly namespaceDeclarations: NamespaceDeclarationMap;
13
+ readonly bodyElement: null;
14
+ readonly root: RootDefinition;
15
+ readonly isTranslated: boolean;
16
+ readonly parent: null;
17
+ readonly children: null;
18
+ readonly attributes: null;
19
+ readonly qualifiedName: QualifiedName;
20
+ constructor(root: RootDefinition, bind: BindDefinition, template: StaticAttribute);
21
+ serializeAttributeXML(): string;
22
+ }
@@ -1,14 +1,8 @@
1
1
  import { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
2
2
  import { QualifiedName } from '../../lib/names/QualifiedName.ts';
3
- import { RootAttributeDefinition } from './RootAttributeDefinition.ts';
4
- import { RootDefinition } from './RootDefinition.ts';
3
+ import { AttributeDefinition } from './AttributeDefinition.ts';
4
+ import { ModelDefinition } from './ModelDefinition.ts';
5
5
  /**
6
- * @todo This can be trivially expanded to a narrowly general case when we
7
- * prioritize work to
8
- * {@link https://github.com/getodk/web-forms/issues/285 | support attributes}
9
- * (as modeled form nodes on par with elements). It's been deferred here to
10
- * avoid expanding scope of an already fairly large yak shave.
11
- *
12
6
  * @todo There's a **much more expansive** general case just waiting for a good
13
7
  * opportuntity to prioritize it. E.g. a `NamedNodeMap<T>`, where T is any
14
8
  * generalized concept of a named node. This expansive generalization would have
@@ -18,7 +12,7 @@ import { RootDefinition } from './RootDefinition.ts';
18
12
  *
19
13
  * @see {@link QualifiedName} for more detail.
20
14
  */
21
- export declare class RootAttributeMap extends Map<QualifiedName, RootAttributeDefinition> {
22
- static from(root: RootDefinition, instanceNode: StaticElement): RootAttributeMap;
15
+ export declare class AttributeDefinitionMap extends Map<QualifiedName, AttributeDefinition> {
16
+ static from(model: ModelDefinition, instanceNode: StaticElement): AttributeDefinitionMap;
23
17
  private constructor();
24
18
  }
@@ -3,8 +3,10 @@ import { NamespaceDeclarationMap } from '../../lib/names/NamespaceDeclarationMap
3
3
  import { QualifiedName } from '../../lib/names/QualifiedName.ts';
4
4
  import { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
5
5
  import { GroupElementDefinition } from '../body/GroupElementDefinition.ts';
6
+ import { AttributeDefinitionMap } from './AttributeDefinitionMap.ts';
6
7
  import { BindDefinition } from './BindDefinition.ts';
7
8
  import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
9
+ import { ModelDefinition } from './ModelDefinition.ts';
8
10
  import { ChildNodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
9
11
  export declare class GroupDefinition extends DescendentNodeDefinition<'group', GroupElementDefinition | null> {
10
12
  readonly template: StaticElement;
@@ -12,6 +14,7 @@ export declare class GroupDefinition extends DescendentNodeDefinition<'group', G
12
14
  readonly namespaceDeclarations: NamespaceDeclarationMap;
13
15
  readonly qualifiedName: QualifiedName;
14
16
  readonly children: readonly ChildNodeDefinition[];
15
- constructor(parent: ParentNodeDefinition, bind: BindDefinition, bodyElement: AnyBodyElementDefinition | null, template: StaticElement);
17
+ readonly attributes: AttributeDefinitionMap;
18
+ constructor(model: ModelDefinition, parent: ParentNodeDefinition, bind: BindDefinition, bodyElement: AnyBodyElementDefinition | null, template: StaticElement);
16
19
  toJSON(): Omit<this, "parent" | "toJSON" | "bind" | "root" | "bodyElement">;
17
20
  }
@@ -13,6 +13,7 @@ export declare class LeafNodeDefinition<V extends ValueType = ValueType> extends
13
13
  readonly namespaceDeclarations: NamespaceDeclarationMap;
14
14
  readonly qualifiedName: QualifiedName;
15
15
  readonly children: null;
16
+ readonly attributes: null;
16
17
  constructor(parent: ParentNodeDefinition, bind: BindDefinition, bodyElement: AnyBodyElementDefinition | null, template: StaticLeafElement);
17
18
  toJSON(): Omit<this, "parent" | "toJSON" | "bind" | "root" | "bodyElement">;
18
19
  }