@getodk/xforms-engine 0.1.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.
- package/README.md +44 -0
- package/dist/.vite/manifest.json +7 -0
- package/dist/XFormDOM.d.ts +31 -0
- package/dist/XFormDataType.d.ts +26 -0
- package/dist/XFormDefinition.d.ts +14 -0
- package/dist/body/BodyDefinition.d.ts +52 -0
- package/dist/body/BodyElementDefinition.d.ts +32 -0
- package/dist/body/RepeatDefinition.d.ts +15 -0
- package/dist/body/UnsupportedBodyElementDefinition.d.ts +10 -0
- package/dist/body/control/ControlDefinition.d.ts +16 -0
- package/dist/body/control/InputDefinition.d.ts +5 -0
- package/dist/body/control/select/ItemDefinition.d.ts +13 -0
- package/dist/body/control/select/ItemsetDefinition.d.ts +16 -0
- package/dist/body/control/select/ItemsetNodesetContext.d.ts +11 -0
- package/dist/body/control/select/ItemsetNodesetExpression.d.ts +5 -0
- package/dist/body/control/select/ItemsetValueExpression.d.ts +6 -0
- package/dist/body/control/select/SelectDefinition.d.ts +23 -0
- package/dist/body/group/BaseGroupDefinition.d.ts +46 -0
- package/dist/body/group/LogicalGroupDefinition.d.ts +6 -0
- package/dist/body/group/PresentationGroupDefinition.d.ts +11 -0
- package/dist/body/group/RepeatGroupDefinition.d.ts +12 -0
- package/dist/body/group/StructuralGroupDefinition.d.ts +6 -0
- package/dist/body/text/HintDefinition.d.ts +11 -0
- package/dist/body/text/LabelDefinition.d.ts +20 -0
- package/dist/body/text/TextElementDefinition.d.ts +32 -0
- package/dist/body/text/TextElementOutputPart.d.ts +12 -0
- package/dist/body/text/TextElementPart.d.ts +12 -0
- package/dist/body/text/TextElementReferencePart.d.ts +6 -0
- package/dist/body/text/TextElementStaticPart.d.ts +6 -0
- package/dist/client/BaseNode.d.ts +138 -0
- package/dist/client/EngineConfig.d.ts +78 -0
- package/dist/client/FormLanguage.d.ts +63 -0
- package/dist/client/GroupNode.d.ts +24 -0
- package/dist/client/OpaqueReactiveObjectFactory.d.ts +70 -0
- package/dist/client/RepeatInstanceNode.d.ts +28 -0
- package/dist/client/RepeatRangeNode.d.ts +94 -0
- package/dist/client/RootNode.d.ts +31 -0
- package/dist/client/SelectNode.d.ts +60 -0
- package/dist/client/StringNode.d.ts +41 -0
- package/dist/client/SubtreeNode.d.ts +52 -0
- package/dist/client/TextRange.d.ts +55 -0
- package/dist/client/hierarchy.d.ts +48 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/node-types.d.ts +1 -0
- package/dist/expression/DependencyContext.d.ts +12 -0
- package/dist/expression/DependentExpression.d.ts +43 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +37622 -0
- package/dist/index.js.map +1 -0
- package/dist/instance/Group.d.ts +31 -0
- package/dist/instance/RepeatInstance.d.ts +60 -0
- package/dist/instance/RepeatRange.d.ts +81 -0
- package/dist/instance/Root.d.ts +70 -0
- package/dist/instance/SelectField.d.ts +45 -0
- package/dist/instance/StringField.d.ts +39 -0
- package/dist/instance/Subtree.d.ts +30 -0
- package/dist/instance/abstract/DescendantNode.d.ts +76 -0
- package/dist/instance/abstract/InstanceNode.d.ts +107 -0
- package/dist/instance/children.d.ts +2 -0
- package/dist/instance/hierarchy.d.ts +12 -0
- package/dist/instance/identity.d.ts +7 -0
- package/dist/instance/index.d.ts +8 -0
- package/dist/instance/internal-api/EvaluationContext.d.ts +34 -0
- package/dist/instance/internal-api/InstanceConfig.d.ts +8 -0
- package/dist/instance/internal-api/SubscribableDependency.d.ts +59 -0
- package/dist/instance/internal-api/TranslationContext.d.ts +4 -0
- package/dist/instance/internal-api/ValueContext.d.ts +22 -0
- package/dist/instance/resource.d.ts +10 -0
- package/dist/instance/text/FormattedTextStub.d.ts +1 -0
- package/dist/instance/text/TextChunk.d.ts +11 -0
- package/dist/instance/text/TextRange.d.ts +10 -0
- package/dist/lib/dom/query.d.ts +20 -0
- package/dist/lib/reactivity/createChildrenState.d.ts +36 -0
- package/dist/lib/reactivity/createComputedExpression.d.ts +12 -0
- package/dist/lib/reactivity/createSelectItems.d.ts +16 -0
- package/dist/lib/reactivity/createValueState.d.ts +44 -0
- package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +18 -0
- package/dist/lib/reactivity/node-state/createClientState.d.ts +9 -0
- package/dist/lib/reactivity/node-state/createCurrentState.d.ts +6 -0
- package/dist/lib/reactivity/node-state/createEngineState.d.ts +5 -0
- package/dist/lib/reactivity/node-state/createSharedNodeState.d.ts +22 -0
- package/dist/lib/reactivity/node-state/createSpecifiedPropertyDescriptor.d.ts +6 -0
- package/dist/lib/reactivity/node-state/createSpecifiedState.d.ts +139 -0
- package/dist/lib/reactivity/node-state/representations.d.ts +25 -0
- package/dist/lib/reactivity/scope.d.ts +23 -0
- package/dist/lib/reactivity/text/createFieldHint.d.ts +5 -0
- package/dist/lib/reactivity/text/createNodeLabel.d.ts +5 -0
- package/dist/lib/reactivity/text/createTextRange.d.ts +19 -0
- package/dist/lib/reactivity/types.d.ts +21 -0
- package/dist/lib/unique-id.d.ts +27 -0
- package/dist/lib/xpath/analysis.d.ts +22 -0
- package/dist/model/BindComputation.d.ts +30 -0
- package/dist/model/BindDefinition.d.ts +31 -0
- package/dist/model/BindElement.d.ts +6 -0
- package/dist/model/DescendentNodeDefinition.d.ts +25 -0
- package/dist/model/ModelBindMap.d.ts +15 -0
- package/dist/model/ModelDefinition.d.ts +10 -0
- package/dist/model/NodeDefinition.d.ts +74 -0
- package/dist/model/RepeatInstanceDefinition.d.ts +15 -0
- package/dist/model/RepeatSequenceDefinition.d.ts +19 -0
- package/dist/model/RepeatTemplateDefinition.d.ts +29 -0
- package/dist/model/RootDefinition.d.ts +24 -0
- package/dist/model/SubtreeDefinition.d.ts +14 -0
- package/dist/model/ValueNodeDefinition.d.ts +15 -0
- package/dist/solid.js +37273 -0
- package/dist/solid.js.map +1 -0
- package/package.json +87 -0
- package/src/XFormDOM.ts +224 -0
- package/src/XFormDataType.ts +64 -0
- package/src/XFormDefinition.ts +40 -0
- package/src/body/BodyDefinition.ts +202 -0
- package/src/body/BodyElementDefinition.ts +62 -0
- package/src/body/RepeatDefinition.ts +54 -0
- package/src/body/UnsupportedBodyElementDefinition.ts +17 -0
- package/src/body/control/ControlDefinition.ts +42 -0
- package/src/body/control/InputDefinition.ts +9 -0
- package/src/body/control/select/ItemDefinition.ts +31 -0
- package/src/body/control/select/ItemsetDefinition.ts +36 -0
- package/src/body/control/select/ItemsetNodesetContext.ts +26 -0
- package/src/body/control/select/ItemsetNodesetExpression.ts +8 -0
- package/src/body/control/select/ItemsetValueExpression.ts +11 -0
- package/src/body/control/select/SelectDefinition.ts +74 -0
- package/src/body/group/BaseGroupDefinition.ts +137 -0
- package/src/body/group/LogicalGroupDefinition.ts +11 -0
- package/src/body/group/PresentationGroupDefinition.ts +28 -0
- package/src/body/group/RepeatGroupDefinition.ts +91 -0
- package/src/body/group/StructuralGroupDefinition.ts +11 -0
- package/src/body/text/HintDefinition.ts +26 -0
- package/src/body/text/LabelDefinition.ts +54 -0
- package/src/body/text/TextElementDefinition.ts +97 -0
- package/src/body/text/TextElementOutputPart.ts +27 -0
- package/src/body/text/TextElementPart.ts +31 -0
- package/src/body/text/TextElementReferencePart.ts +21 -0
- package/src/body/text/TextElementStaticPart.ts +26 -0
- package/src/client/BaseNode.ts +180 -0
- package/src/client/EngineConfig.ts +83 -0
- package/src/client/FormLanguage.ts +77 -0
- package/src/client/GroupNode.ts +33 -0
- package/src/client/OpaqueReactiveObjectFactory.ts +100 -0
- package/src/client/README.md +39 -0
- package/src/client/RepeatInstanceNode.ts +41 -0
- package/src/client/RepeatRangeNode.ts +100 -0
- package/src/client/RootNode.ts +36 -0
- package/src/client/SelectNode.ts +69 -0
- package/src/client/StringNode.ts +46 -0
- package/src/client/SubtreeNode.ts +57 -0
- package/src/client/TextRange.ts +63 -0
- package/src/client/hierarchy.ts +63 -0
- package/src/client/index.ts +29 -0
- package/src/client/node-types.ts +10 -0
- package/src/expression/DependencyContext.ts +53 -0
- package/src/expression/DependentExpression.ts +102 -0
- package/src/index.ts +35 -0
- package/src/instance/Group.ts +82 -0
- package/src/instance/RepeatInstance.ts +164 -0
- package/src/instance/RepeatRange.ts +214 -0
- package/src/instance/Root.ts +264 -0
- package/src/instance/SelectField.ts +204 -0
- package/src/instance/StringField.ts +93 -0
- package/src/instance/Subtree.ts +79 -0
- package/src/instance/abstract/DescendantNode.ts +182 -0
- package/src/instance/abstract/InstanceNode.ts +257 -0
- package/src/instance/children.ts +52 -0
- package/src/instance/hierarchy.ts +54 -0
- package/src/instance/identity.ts +11 -0
- package/src/instance/index.ts +37 -0
- package/src/instance/internal-api/EvaluationContext.ts +41 -0
- package/src/instance/internal-api/InstanceConfig.ts +9 -0
- package/src/instance/internal-api/SubscribableDependency.ts +61 -0
- package/src/instance/internal-api/TranslationContext.ts +5 -0
- package/src/instance/internal-api/ValueContext.ts +27 -0
- package/src/instance/resource.ts +75 -0
- package/src/instance/text/FormattedTextStub.ts +8 -0
- package/src/instance/text/TextChunk.ts +20 -0
- package/src/instance/text/TextRange.ts +23 -0
- package/src/lib/dom/query.ts +49 -0
- package/src/lib/reactivity/createChildrenState.ts +60 -0
- package/src/lib/reactivity/createComputedExpression.ts +114 -0
- package/src/lib/reactivity/createSelectItems.ts +163 -0
- package/src/lib/reactivity/createValueState.ts +258 -0
- package/src/lib/reactivity/materializeCurrentStateChildren.ts +121 -0
- package/src/lib/reactivity/node-state/createClientState.ts +51 -0
- package/src/lib/reactivity/node-state/createCurrentState.ts +27 -0
- package/src/lib/reactivity/node-state/createEngineState.ts +18 -0
- package/src/lib/reactivity/node-state/createSharedNodeState.ts +79 -0
- package/src/lib/reactivity/node-state/createSpecifiedPropertyDescriptor.ts +85 -0
- package/src/lib/reactivity/node-state/createSpecifiedState.ts +229 -0
- package/src/lib/reactivity/node-state/representations.ts +64 -0
- package/src/lib/reactivity/scope.ts +106 -0
- package/src/lib/reactivity/text/createFieldHint.ts +16 -0
- package/src/lib/reactivity/text/createNodeLabel.ts +16 -0
- package/src/lib/reactivity/text/createTextRange.ts +155 -0
- package/src/lib/reactivity/types.ts +27 -0
- package/src/lib/unique-id.ts +34 -0
- package/src/lib/xpath/analysis.ts +241 -0
- package/src/model/BindComputation.ts +88 -0
- package/src/model/BindDefinition.ts +104 -0
- package/src/model/BindElement.ts +8 -0
- package/src/model/DescendentNodeDefinition.ts +56 -0
- package/src/model/ModelBindMap.ts +71 -0
- package/src/model/ModelDefinition.ts +19 -0
- package/src/model/NodeDefinition.ts +146 -0
- package/src/model/RepeatInstanceDefinition.ts +39 -0
- package/src/model/RepeatSequenceDefinition.ts +53 -0
- package/src/model/RepeatTemplateDefinition.ts +150 -0
- package/src/model/RootDefinition.ts +121 -0
- package/src/model/SubtreeDefinition.ts +50 -0
- package/src/model/ValueNodeDefinition.ts +39 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { AnyNodeDefinition } from '../model/NodeDefinition.ts';
|
|
2
|
+
import type { InstanceNodeType } from './node-types.js';
|
|
3
|
+
import type { TextRange } from './TextRange.ts';
|
|
4
|
+
export interface BaseNodeState {
|
|
5
|
+
/**
|
|
6
|
+
* Location path reference to the node's primary instance state. This property
|
|
7
|
+
* may change if a node's position changes, e.g. when a repeat instance is
|
|
8
|
+
* removed. Its potential reactivity allows nodes to re-run computations which
|
|
9
|
+
* depend on the node's position itself, or when any other relative reference
|
|
10
|
+
* might target different nodes as a result of the positional change.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* /data/repeat[1]/foo
|
|
14
|
+
* /data/repeat[2]/foo
|
|
15
|
+
*/
|
|
16
|
+
get reference(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Note: a node's `readonly` state may become `true` by inheriting that state
|
|
19
|
+
* from one of its ancestors. Computing this inheritance is handled by the
|
|
20
|
+
* engine, but it may be of interest to clients.
|
|
21
|
+
*
|
|
22
|
+
* In the future, a more granular type might convey this detail more
|
|
23
|
+
* explicitly (at the expense of a more complex type). For now, a client can
|
|
24
|
+
* infer that inheritance by visiting the
|
|
25
|
+
* {@link BaseNode.parent | parent node}.
|
|
26
|
+
*/
|
|
27
|
+
get readonly(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Note: a node's `relevant` state may become `false` by inheriting that state
|
|
30
|
+
* from one of its ancestors. Computing this inheritance is handled by the
|
|
31
|
+
* engine, but it may be of interest to clients.
|
|
32
|
+
*
|
|
33
|
+
* In the future, a more granular type might convey this detail more
|
|
34
|
+
* explicitly (at the expense of a more complex type). For now, a client can
|
|
35
|
+
* infer that inheritance by visiting the
|
|
36
|
+
* {@link BaseNode.parent | parent node}.
|
|
37
|
+
*/
|
|
38
|
+
get relevant(): boolean;
|
|
39
|
+
get required(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Interfaces for nodes which cannot provide a label should override this to
|
|
42
|
+
* specify that the property will always be `null`.
|
|
43
|
+
*/
|
|
44
|
+
get label(): TextRange<'label'> | null;
|
|
45
|
+
/**
|
|
46
|
+
* Interfaces for nodes which cannot provide a hint should override this to
|
|
47
|
+
* specify that the property will always be `null`.
|
|
48
|
+
*/
|
|
49
|
+
get hint(): TextRange<'hint'> | null;
|
|
50
|
+
/**
|
|
51
|
+
* Each node's children (if it is a parent node) will be accessed on that
|
|
52
|
+
* node's state. While some node types will technically have static children,
|
|
53
|
+
* other nodes' children will be stateful (i.e. repeats). For a client, both
|
|
54
|
+
* cases are accessed the same way for consistency.
|
|
55
|
+
*
|
|
56
|
+
* Certain kinds of nodes are considered parent nodes: they may have child
|
|
57
|
+
* nodes. In some cases (presently, repeat ranges), children may be added or
|
|
58
|
+
* removed while a user is filling a form. As such, those children must be
|
|
59
|
+
* accessed as part of the node's
|
|
60
|
+
* {@link BaseNode.currentState | current state}. (In contrast, child nodes
|
|
61
|
+
* are never moved between different parents, so their
|
|
62
|
+
* {@link BaseNode.parent | parent} is static rather than part of their
|
|
63
|
+
* current state).
|
|
64
|
+
*
|
|
65
|
+
* A node is either:
|
|
66
|
+
*
|
|
67
|
+
* - Always a parent, in which case its `children` state should always produce
|
|
68
|
+
* an array. When the parent node's children can be added or removed, an
|
|
69
|
+
* empty array should be used to represent the absence of any children in
|
|
70
|
+
* its current state.
|
|
71
|
+
* - Never a parent, in which case its `children` state should always produce
|
|
72
|
+
* `null`. Such a node will instead have a {@link value}.
|
|
73
|
+
*/
|
|
74
|
+
get children(): readonly BaseNode[] | null;
|
|
75
|
+
/**
|
|
76
|
+
* Certain kinds of nodes restrict their {@link value} to a specific set of
|
|
77
|
+
* valid values. Where they do, they will provide a collection (typically an
|
|
78
|
+
* array) of those values. This collection may be updated depending on other
|
|
79
|
+
* aspects of form state, which is why it is treated as a part of the node's
|
|
80
|
+
* state.
|
|
81
|
+
*
|
|
82
|
+
* Nodes which do not have this restriction (including nodes which cannot have
|
|
83
|
+
* a value at all) will always produce `valueOptions: null`.
|
|
84
|
+
*/
|
|
85
|
+
get valueOptions(): unknown;
|
|
86
|
+
/**
|
|
87
|
+
* Certain kinds of nodes store a value state. Where they do, they will
|
|
88
|
+
* specify the type of the value directly.
|
|
89
|
+
*
|
|
90
|
+
* Parent nodes, i.e. nodes which can contain {@link children}, do not store a
|
|
91
|
+
* value state. For those nodes, their value state should always be `null`.
|
|
92
|
+
*/
|
|
93
|
+
get value(): unknown;
|
|
94
|
+
}
|
|
95
|
+
type FormNodeID = string;
|
|
96
|
+
/**
|
|
97
|
+
* Base interface for common/shared aspects of any node type.
|
|
98
|
+
*/
|
|
99
|
+
export interface BaseNode {
|
|
100
|
+
/**
|
|
101
|
+
* Specifies the node's general type. This can be useful for narrowing types,
|
|
102
|
+
* e.g. those of children.
|
|
103
|
+
*/
|
|
104
|
+
readonly nodeType: InstanceNodeType;
|
|
105
|
+
/**
|
|
106
|
+
* Each node has a unique identifier. This identifier is stable throughout
|
|
107
|
+
* the lifetime of an active session filling a form.
|
|
108
|
+
*/
|
|
109
|
+
readonly nodeId: FormNodeID;
|
|
110
|
+
/**
|
|
111
|
+
* Each node has a definition which specifies aspects of the node defined in
|
|
112
|
+
* the form. These aspects include (but are not limited to) the node's data
|
|
113
|
+
* type, its body presentation constraints (if any), its bound nodeset, and
|
|
114
|
+
* so on...
|
|
115
|
+
*
|
|
116
|
+
* @todo Interfaces for specific (non-base) node types should override this
|
|
117
|
+
* to specify the actual (concrete or union) type of their `definition`.
|
|
118
|
+
*/
|
|
119
|
+
readonly definition: AnyNodeDefinition;
|
|
120
|
+
/**
|
|
121
|
+
* Each node links back to the node representing the root of the form.
|
|
122
|
+
*
|
|
123
|
+
* @todo Interfaces for all concrete node types should override this to
|
|
124
|
+
* specify the actual root node type.
|
|
125
|
+
*/
|
|
126
|
+
readonly root: BaseNode;
|
|
127
|
+
/**
|
|
128
|
+
* Each node links back to its parent, if any. All nodes have a parent except
|
|
129
|
+
* the form's {@link root}.
|
|
130
|
+
*/
|
|
131
|
+
readonly parent: BaseNode | null;
|
|
132
|
+
/**
|
|
133
|
+
* Each node provides a discrete object representing the stateful aspects of
|
|
134
|
+
* that node which will change over time. When a client provides a {@link OpaqueReactiveObjectFactory}
|
|
135
|
+
*/
|
|
136
|
+
readonly currentState: BaseNodeState;
|
|
137
|
+
}
|
|
138
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { OpaqueReactiveObjectFactory } from './OpaqueReactiveObjectFactory.ts';
|
|
2
|
+
/**
|
|
3
|
+
* @todo this is currently a strict subset of the web standard `Response`. Is it
|
|
4
|
+
* sufficient? Ways it might not be:
|
|
5
|
+
*
|
|
6
|
+
* - No way to convey metadata about the resource
|
|
7
|
+
* - Ambiguous if a client supplies an alternative implementation which doesn't
|
|
8
|
+
* exhaust the body on access
|
|
9
|
+
*/
|
|
10
|
+
export interface FetchResourceResponse {
|
|
11
|
+
readonly ok?: boolean;
|
|
12
|
+
readonly body?: ReadableStream<Uint8Array> | null;
|
|
13
|
+
readonly bodyUsed?: boolean;
|
|
14
|
+
readonly blob: () => Promise<Blob>;
|
|
15
|
+
readonly text: () => Promise<string>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @todo this is a strict subset of the web standard `fetch` interface. It
|
|
19
|
+
* implicitly assumes that the engine itself will only ever issue `GET`-like
|
|
20
|
+
* requests. It also provides no further request-like semantics to the engine.
|
|
21
|
+
* This is presumed sufficient for now, but notably doesn't expose any notion of
|
|
22
|
+
* content negotiation (e.g. the ability to supply `Accept` headers).
|
|
23
|
+
*
|
|
24
|
+
* This also completely ignores any notion of mapping
|
|
25
|
+
* {@link https://getodk.github.io/xforms-spec/#uris | `jr:` URLs} to their
|
|
26
|
+
* actual resources (likely, but not necessarily, accessed at a corresponding
|
|
27
|
+
* HTTP URL).
|
|
28
|
+
*/
|
|
29
|
+
export type FetchResource = (resource: URL) => Promise<FetchResourceResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Options provided by a client to specify certain aspects of engine runtime
|
|
32
|
+
* behavior. These options will generally be intended to facilitate cooperation
|
|
33
|
+
* where there is mixed responsibility between a client and the engine, or where
|
|
34
|
+
* the engine may provide sensible defaults which a client could be expected to
|
|
35
|
+
* override or augment.
|
|
36
|
+
*/
|
|
37
|
+
export interface EngineConfig {
|
|
38
|
+
/**
|
|
39
|
+
* A client may specify a generic function for constructing stateful objects.
|
|
40
|
+
* The only hard requirement of this function is that it accepts an **object**
|
|
41
|
+
* and returns an object of the same shape. The engine will use this function
|
|
42
|
+
* to initialize client-facing state, and will mutate properties of the object
|
|
43
|
+
* when their corresponding state is changed.
|
|
44
|
+
*
|
|
45
|
+
* A client may use this function to provide its own implementation of
|
|
46
|
+
* reactivity with semantics like those described above. The mechanism of
|
|
47
|
+
* reactivity, if any, is at the discretion of the client. It is expected
|
|
48
|
+
* that clients providing this function will use a reactive subscribe-on-read
|
|
49
|
+
* mechanism to handle state updates conveyed by the engine.
|
|
50
|
+
*/
|
|
51
|
+
readonly stateFactory?: OpaqueReactiveObjectFactory;
|
|
52
|
+
/**
|
|
53
|
+
* A client may specify a generic function for retrieving resources referenced
|
|
54
|
+
* by a form, such as:
|
|
55
|
+
*
|
|
56
|
+
* - Form definitions themselves (if not provided directly to the engine by
|
|
57
|
+
* the client)
|
|
58
|
+
* - External secondary instances
|
|
59
|
+
* - Media (images, audio, video, etc.)
|
|
60
|
+
*
|
|
61
|
+
* The function is expected to be a subset of the
|
|
62
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API},
|
|
63
|
+
* performing `GET` requests for:
|
|
64
|
+
*
|
|
65
|
+
* - Text resources (e.g. XML, CSV, JSON/GeoJSON)
|
|
66
|
+
* - Binary resources (e.g. media)
|
|
67
|
+
* - Optionally streamed binary data of either (e.g. for optimized
|
|
68
|
+
* presentation of audio/video)
|
|
69
|
+
*
|
|
70
|
+
* If provided by a client, this function will be used by the engine to
|
|
71
|
+
* retrieve any such resource, as required for engine functionality. If
|
|
72
|
+
* absent, the engine will use the native `fetch` function (if available, a
|
|
73
|
+
* polyfill otherwise). Clients may use this function to provide resources
|
|
74
|
+
* from sources other than the network, (or even in a test client to provide
|
|
75
|
+
* e.g. resources from test fixtures).
|
|
76
|
+
*/
|
|
77
|
+
readonly fetchResource?: FetchResource;
|
|
78
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
interface BaseFormLanguage {
|
|
2
|
+
/**
|
|
3
|
+
* @see {@link ActiveLanguage} for details.
|
|
4
|
+
*/
|
|
5
|
+
readonly isSyntheticDefault?: true;
|
|
6
|
+
/**
|
|
7
|
+
* As derived directly from the form's
|
|
8
|
+
* {@link https://getodk.github.io/xforms-spec/#languages | `itext` translations}.
|
|
9
|
+
*/
|
|
10
|
+
readonly language: string;
|
|
11
|
+
/**
|
|
12
|
+
* Where possible, a form's languages may detect the standardized locale
|
|
13
|
+
* corresponding to the language as specified in the form.
|
|
14
|
+
*/
|
|
15
|
+
readonly locale?: Intl.Locale;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @see {@link ActiveLanguage} for details.
|
|
19
|
+
*/
|
|
20
|
+
export interface SyntheticDefaultLanguage extends BaseFormLanguage {
|
|
21
|
+
readonly isSyntheticDefault: true;
|
|
22
|
+
readonly language: '';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A language available for a given form, as defined by that form's {@link https://getodk.github.io/xforms-spec/#languages | `itext` translations}.
|
|
26
|
+
*
|
|
27
|
+
* @see {@link ActiveLanguage} for additional details.
|
|
28
|
+
*/
|
|
29
|
+
export interface FormLanguage extends BaseFormLanguage {
|
|
30
|
+
readonly isSyntheticDefault?: never;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A form with translations will always have one or more {@link FormLanguage}s,
|
|
34
|
+
* with the default chosen as described in the ODK XForms specification.
|
|
35
|
+
*
|
|
36
|
+
* A form that specifies no translations will always have a single
|
|
37
|
+
* {@link SyntheticDefaultLanguage}.
|
|
38
|
+
*
|
|
39
|
+
* No form will ever combine both types of language.
|
|
40
|
+
*
|
|
41
|
+
* This distinction is intended to avoid confusion about the **potential** state
|
|
42
|
+
* of a form's active language. A naive type to express the possibility, without
|
|
43
|
+
* a synthetic default, would be something like `FormLanguage | null`, which
|
|
44
|
+
* would seem to suggest to a client that a form may **only sometimes** have an
|
|
45
|
+
* active language—for instance, that there might be a way for a client to turn
|
|
46
|
+
* translation off and on.
|
|
47
|
+
*
|
|
48
|
+
* By ensuring there is always _some active language value_, and by expressing
|
|
49
|
+
* the {@link FormLanguages} type to correspond to each of the possibilities
|
|
50
|
+
* discussed above, it's hoped that the set of potential translation states a
|
|
51
|
+
* client might encounter/establish are more clear.
|
|
52
|
+
*/
|
|
53
|
+
export type ActiveLanguage = FormLanguage | SyntheticDefaultLanguage;
|
|
54
|
+
/**
|
|
55
|
+
* A form may either have:
|
|
56
|
+
*
|
|
57
|
+
* - one or more available {@link FormLanguage}s, as defined by the form
|
|
58
|
+
* - exactly one {@link SyntheticDefaultLanguage}
|
|
59
|
+
*
|
|
60
|
+
* @see {@link ActiveLanguage} for additional details.
|
|
61
|
+
*/
|
|
62
|
+
export type FormLanguages = readonly [FormLanguage, ...FormLanguage[]] | readonly [SyntheticDefaultLanguage];
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { NonRepeatGroupElementDefinition } from '../body/BodyDefinition.ts';
|
|
2
|
+
import type { SubtreeDefinition } from '../model/SubtreeDefinition.ts';
|
|
3
|
+
import type { BaseNode, BaseNodeState } from './BaseNode.ts';
|
|
4
|
+
import type { RootNode } from './RootNode.ts';
|
|
5
|
+
import type { GeneralChildNode, GeneralParentNode } from './hierarchy.ts';
|
|
6
|
+
export interface GroupNodeState extends BaseNodeState {
|
|
7
|
+
get hint(): null;
|
|
8
|
+
get children(): readonly GeneralChildNode[];
|
|
9
|
+
get valueOptions(): null;
|
|
10
|
+
get value(): null;
|
|
11
|
+
}
|
|
12
|
+
export interface GroupDefinition extends SubtreeDefinition {
|
|
13
|
+
readonly bodyElement: NonRepeatGroupElementDefinition;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A node corresponding to an XForms `<group>`.
|
|
17
|
+
*/
|
|
18
|
+
export interface GroupNode extends BaseNode {
|
|
19
|
+
readonly nodeType: 'group';
|
|
20
|
+
readonly definition: GroupDefinition;
|
|
21
|
+
readonly root: RootNode;
|
|
22
|
+
readonly parent: GeneralParentNode;
|
|
23
|
+
readonly currentState: GroupNodeState;
|
|
24
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
interface BaseOpaqueReactiveObjectFactory<in out Input extends object = object> {
|
|
2
|
+
<T extends Input>(object: T): T;
|
|
3
|
+
<T extends object>(object: T): T;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* A client-provided reactivity factory. We assume little about the mechanism
|
|
7
|
+
* of reactivity a client provides (and a client may opt to provide no reactive
|
|
8
|
+
* mechanism at all, if it will consume state changes by other means). From an
|
|
9
|
+
* API perspective, the expectation is:
|
|
10
|
+
*
|
|
11
|
+
* - The factory accepts a single argument, which **MUST** be an object.
|
|
12
|
+
* Reactive primitive values are unsupported by this interface.
|
|
13
|
+
* - The factory **MUST** return an object of the same shape (i.e. it must
|
|
14
|
+
* have the same property key/value pairs).
|
|
15
|
+
* - The factory's return object **MUST** be mutable by the web-forms engine.
|
|
16
|
+
* - The web-forms engine **WILL** propagate changes to state as they occur,
|
|
17
|
+
* by mutating properties of the object corresponding to those aspects of
|
|
18
|
+
* state.
|
|
19
|
+
* - The client **MAY** read any property of the factory's returned object.
|
|
20
|
+
* - Because the client's reactivity mechanism (if any) is unknown, it is
|
|
21
|
+
* **ASSUMED** that the engine's mutations are observable by the client,
|
|
22
|
+
* and that the client has a defined means to subscribe to those mutations.
|
|
23
|
+
* It is **IMPLIED** (but **NOT REQUIRED**) that the typical reactive client
|
|
24
|
+
* will subscribe to mutations by reading the pertinent properties of the
|
|
25
|
+
* reactive object in a reactive context appropriate for that client.
|
|
26
|
+
* - In common usage, the engine **MAY** convey computed getter property types
|
|
27
|
+
* back to the client, to indicate that certain aspects the engine mutates
|
|
28
|
+
* are read-only to the client (even if they are mutable by the engine).
|
|
29
|
+
*
|
|
30
|
+
* Real world examples of reactive implementations include:
|
|
31
|
+
*
|
|
32
|
+
* - {@link https://vuejs.org/api/reactivity-core.html#reactive | `reactive` (Vue)}
|
|
33
|
+
* - {@link https://docs.solidjs.com/reference/store-utilities/create-mutable | `createMutable` (Solid)}
|
|
34
|
+
* - {@link DefineMutableObject | our internal `mutable` test helper}
|
|
35
|
+
*
|
|
36
|
+
* Each of these implementations are targeted as part of our effort to ensure
|
|
37
|
+
* the `xforms-engine` is agnostic to a client's framework and/or implementation
|
|
38
|
+
* of state.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* declare const clientFactory: OpaqueReactiveObjectFactory;
|
|
44
|
+
*
|
|
45
|
+
* interface ClientFoo {
|
|
46
|
+
* get bar(): string;
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* interface MutableFoo {
|
|
50
|
+
* bar: string;
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
53
|
+
* // State internally updated by engine
|
|
54
|
+
* let mutableFoo = clientFactory<MutableFoo>({ bar: 'bat' });
|
|
55
|
+
*
|
|
56
|
+
* // Same state, consumed by the client as computed but read-only
|
|
57
|
+
* let clientFoo: ClientFoo = engineFoo;
|
|
58
|
+
*
|
|
59
|
+
* // Client: subscribe to mutations by the engine
|
|
60
|
+
* reactiveContext(() => {
|
|
61
|
+
* // Implied client subscription to `clientFoo.bar` on property access
|
|
62
|
+
* doSomethingWith(clientFoo.bar);
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* // Engine: mutate values to convey state changes to subscribed client
|
|
66
|
+
* engineFoo.bar = 'quux';
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export type OpaqueReactiveObjectFactory<Input extends object = object> = BaseOpaqueReactiveObjectFactory<Input> & ((object: object) => unknown);
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { RepeatInstanceDefinition } from '../model/RepeatInstanceDefinition.ts';
|
|
2
|
+
import type { RepeatTemplateDefinition } from '../model/RepeatTemplateDefinition.ts';
|
|
3
|
+
import type { BaseNode, BaseNodeState } from './BaseNode.ts';
|
|
4
|
+
import type { RepeatRangeNode } from './RepeatRangeNode.ts';
|
|
5
|
+
import type { RootNode } from './RootNode.ts';
|
|
6
|
+
import type { GeneralChildNode } from './hierarchy.ts';
|
|
7
|
+
export interface RepeatInstanceNodeState extends BaseNodeState {
|
|
8
|
+
get hint(): null;
|
|
9
|
+
get children(): readonly GeneralChildNode[];
|
|
10
|
+
get valueOptions(): null;
|
|
11
|
+
get value(): null;
|
|
12
|
+
}
|
|
13
|
+
export type RepeatDefinition = RepeatInstanceDefinition | RepeatTemplateDefinition;
|
|
14
|
+
export interface RepeatInstanceNode extends BaseNode {
|
|
15
|
+
readonly nodeType: 'repeat-instance';
|
|
16
|
+
readonly definition: RepeatDefinition;
|
|
17
|
+
readonly root: RootNode;
|
|
18
|
+
/**
|
|
19
|
+
* A repeat instance may only be a child of a {@link RepeatRangeNode}.
|
|
20
|
+
*
|
|
21
|
+
* Note: the web-forms engine's representation of this structure differs from
|
|
22
|
+
* the underlying XForms specification's primary instance structure.
|
|
23
|
+
*
|
|
24
|
+
* @see {@link RepeatRangeNode} for additional detail.
|
|
25
|
+
*/
|
|
26
|
+
readonly parent: RepeatRangeNode;
|
|
27
|
+
readonly currentState: RepeatInstanceNodeState;
|
|
28
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { RepeatSequenceDefinition } from '../model/RepeatSequenceDefinition.ts';
|
|
2
|
+
import type { BaseNode, BaseNodeState } from './BaseNode.ts';
|
|
3
|
+
import type { RepeatInstanceNode } from './RepeatInstanceNode.ts';
|
|
4
|
+
import type { RootNode } from './RootNode.ts';
|
|
5
|
+
import type { TextRange } from './TextRange.ts';
|
|
6
|
+
import type { GeneralParentNode } from './hierarchy.ts';
|
|
7
|
+
export interface RepeatRangeNodeState extends BaseNodeState {
|
|
8
|
+
get hint(): null;
|
|
9
|
+
get label(): TextRange<'label'> | null;
|
|
10
|
+
/**
|
|
11
|
+
* A repeat range's children may only be {@link RepeatInstanceNode}s.
|
|
12
|
+
*
|
|
13
|
+
* Note: the web-forms engine's representation of this structure differs from
|
|
14
|
+
* the underlying XForms specification's primary instance structure.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link RepeatRangeNode} for additional detail.
|
|
17
|
+
*/
|
|
18
|
+
get children(): readonly RepeatInstanceNode[];
|
|
19
|
+
get valueOptions(): null;
|
|
20
|
+
get value(): null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Represents a contiguous set of zero or more {@link RepeatInstanceNode}s
|
|
24
|
+
* (accessed by its
|
|
25
|
+
* {@link RepeatRangeNodeState.children | `currentState.children`}).
|
|
26
|
+
*
|
|
27
|
+
* This structure is modeled as a node, like any other, in the web-forms engine
|
|
28
|
+
* representation, which notably differs from the corresponding structure in the
|
|
29
|
+
* underlying ODK XForms specification's primary instance state.
|
|
30
|
+
*
|
|
31
|
+
* _Conceptually_, it more closely corresponds to the concept of a set of
|
|
32
|
+
* repeats as defined by a `<repeat>` element in the XForms body. Whereas its
|
|
33
|
+
* {@link RepeatInstanceNode} children, if any, correspond directly to the
|
|
34
|
+
* XForms primary instance's state.
|
|
35
|
+
*
|
|
36
|
+
* More precisely, clients should be advised that the presentation aspect of a
|
|
37
|
+
* `RepeatRangeNode` corresponds to a pair of
|
|
38
|
+
* {@link https://getodk.github.io/xforms-spec/#body-elements | `<group>` and `<repeat>` body elements}
|
|
39
|
+
* referencing the same nodeset. (Forms which define a repeat without a
|
|
40
|
+
* corresponding group are semantically equivalent to those with this
|
|
41
|
+
* group/repeat pair. The web-forms engine model simplifies this by producing
|
|
42
|
+
* the same runtime structure for either case.)
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
*
|
|
46
|
+
* To illustrate the structural divergence from the underlying XForms concepts,
|
|
47
|
+
* consider this (abridged) XForm definition:
|
|
48
|
+
*
|
|
49
|
+
* ```xml
|
|
50
|
+
* <!-- /h:html/h:head/model -->
|
|
51
|
+
* <instance>
|
|
52
|
+
* <data>
|
|
53
|
+
* <rep />
|
|
54
|
+
* </data>
|
|
55
|
+
* </instance>
|
|
56
|
+
* <!-- /h:html/h:body -->
|
|
57
|
+
* <repeat nodeset="/data/rep" />
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* The engine's representation maps to that structure roughly like:
|
|
61
|
+
*
|
|
62
|
+
* ```xml
|
|
63
|
+
* <!-- /h:html/h:head/model -->
|
|
64
|
+
* <instance>
|
|
65
|
+
* <data>
|
|
66
|
+
* <!-- RepeatRangeNode(/data/rep).currentState.children: [ -->
|
|
67
|
+
* <!-- RepeatInstanceNode(/data/rep[1]): --> <rep />
|
|
68
|
+
* <!-- RepeatInstanceNode(/data/rep[2]): --> <rep />
|
|
69
|
+
* <!-- ... -->
|
|
70
|
+
* <!-- ] -->
|
|
71
|
+
* </data>
|
|
72
|
+
* </instance>
|
|
73
|
+
* <!-- /h:html/h:body -->
|
|
74
|
+
* <!-- RepeatRangeNode(/data/rep).definition: { ... -->
|
|
75
|
+
* <group ref="/data/rep">
|
|
76
|
+
* <repeat nodeset="/data/rep" />
|
|
77
|
+
* </group>
|
|
78
|
+
* <!-- } -->
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* Importantly, if the state of a given repeat range has no instances, no aspect
|
|
82
|
+
* of these repeats will be present in the underlying XForms primary instance
|
|
83
|
+
* state, but the web-forms engine's representations **retains a reference** to
|
|
84
|
+
* its {@link RepeatRangeNode}.
|
|
85
|
+
*/
|
|
86
|
+
export interface RepeatRangeNode extends BaseNode {
|
|
87
|
+
readonly nodeType: 'repeat-range';
|
|
88
|
+
readonly definition: RepeatSequenceDefinition;
|
|
89
|
+
readonly root: RootNode;
|
|
90
|
+
readonly parent: GeneralParentNode;
|
|
91
|
+
readonly currentState: RepeatRangeNodeState;
|
|
92
|
+
addInstances(afterIndex?: number, count?: number): RootNode;
|
|
93
|
+
removeInstances(startIndex: number, count?: number): RootNode;
|
|
94
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RootDefinition } from '../model/RootDefinition.ts';
|
|
2
|
+
import type { BaseNode, BaseNodeState } from './BaseNode.ts';
|
|
3
|
+
import type { ActiveLanguage, FormLanguage, FormLanguages } from './FormLanguage.ts';
|
|
4
|
+
import type { GeneralChildNode } from './hierarchy.ts';
|
|
5
|
+
export interface RootNodeState extends BaseNodeState {
|
|
6
|
+
/**
|
|
7
|
+
* This, along with {@link RootNode.languages} is the most significant break
|
|
8
|
+
in consistency across node types' state and static properties. Exposing it
|
|
9
|
+
across all node types seems like a point of potential confusion, so this
|
|
10
|
+
particular divergence seems like the most reasonable compromise.
|
|
11
|
+
*/
|
|
12
|
+
get activeLanguage(): ActiveLanguage;
|
|
13
|
+
get label(): null;
|
|
14
|
+
get hint(): null;
|
|
15
|
+
get children(): readonly GeneralChildNode[];
|
|
16
|
+
get valueOptions(): null;
|
|
17
|
+
get value(): null;
|
|
18
|
+
}
|
|
19
|
+
export interface RootNode extends BaseNode {
|
|
20
|
+
readonly nodeType: 'root';
|
|
21
|
+
readonly definition: RootDefinition;
|
|
22
|
+
readonly root: RootNode;
|
|
23
|
+
readonly parent: null;
|
|
24
|
+
readonly currentState: RootNodeState;
|
|
25
|
+
/**
|
|
26
|
+
* @todo as with {@link RootNodeState.activeLanguage}, this is the most
|
|
27
|
+
* significant break in consistency across node types.
|
|
28
|
+
*/
|
|
29
|
+
readonly languages: FormLanguages;
|
|
30
|
+
setLanguage(language: FormLanguage): RootNode;
|
|
31
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { AnySelectDefinition } from '../body/control/select/SelectDefinition.ts';
|
|
2
|
+
import type { ValueNodeDefinition } from '../model/ValueNodeDefinition.ts';
|
|
3
|
+
import type { BaseNode, BaseNodeState } from './BaseNode.ts';
|
|
4
|
+
import type { RootNode } from './RootNode.ts';
|
|
5
|
+
import type { TextRange } from './TextRange.ts';
|
|
6
|
+
import type { GeneralParentNode } from './hierarchy.ts';
|
|
7
|
+
export interface SelectItem {
|
|
8
|
+
get value(): string;
|
|
9
|
+
get label(): TextRange<'label'> | null;
|
|
10
|
+
}
|
|
11
|
+
export interface SelectNodeState extends BaseNodeState {
|
|
12
|
+
get children(): null;
|
|
13
|
+
/**
|
|
14
|
+
* @todo should {@link BaseNodeState} include this??
|
|
15
|
+
*/
|
|
16
|
+
get valueOptions(): readonly SelectItem[];
|
|
17
|
+
/**
|
|
18
|
+
* This value is treated as set-like by the engine, where each
|
|
19
|
+
* {@link SelectItem.value | item's `value`} may occur once (at most), and:
|
|
20
|
+
*
|
|
21
|
+
* - Fields defined with an XForms `<select>` may contain multiple items
|
|
22
|
+
* - Fields defined with an XForms `<select1>` will always produce one item
|
|
23
|
+
* (at most)
|
|
24
|
+
*
|
|
25
|
+
* @todo Maybe it makes more sense for the client interface to break these up!
|
|
26
|
+
* Should a `SelectNodeState` have this `value` type, whereas a hypothetical
|
|
27
|
+
* `Select1NodeState` would have `get value(): SelectItem | null`?
|
|
28
|
+
*/
|
|
29
|
+
get value(): readonly SelectItem[];
|
|
30
|
+
}
|
|
31
|
+
export interface SelectDefinition extends ValueNodeDefinition {
|
|
32
|
+
readonly bodyElement: AnySelectDefinition;
|
|
33
|
+
}
|
|
34
|
+
export interface SelectNode extends BaseNode {
|
|
35
|
+
readonly nodeType: 'select';
|
|
36
|
+
readonly definition: SelectDefinition;
|
|
37
|
+
readonly root: RootNode;
|
|
38
|
+
readonly parent: GeneralParentNode;
|
|
39
|
+
readonly currentState: SelectNodeState;
|
|
40
|
+
/**
|
|
41
|
+
* For use by a client to update the selection of a select node where:
|
|
42
|
+
*
|
|
43
|
+
* - For fields defined with an XForms `<select>`, calling this method is
|
|
44
|
+
* additive, i.e. it will include the item in its
|
|
45
|
+
* {@link SelectNodeState.value}.
|
|
46
|
+
* - For fields defined with an XForms `<select1>`, calling this method will
|
|
47
|
+
* replace the selection (if any).
|
|
48
|
+
*
|
|
49
|
+
* @todo @see {@link StringNode.setValue} re: write restrictions
|
|
50
|
+
* @todo @see {@link SelectNodeState.value} re: breaking up the types
|
|
51
|
+
*/
|
|
52
|
+
select(item: SelectItem): RootNode;
|
|
53
|
+
/**
|
|
54
|
+
* For use by a client to remove an item from the node's
|
|
55
|
+
* {@link SelectNodeState.value}.
|
|
56
|
+
*
|
|
57
|
+
* @todo @see {@link StringNode.setValue} re: write restrictions
|
|
58
|
+
*/
|
|
59
|
+
deselect(item: SelectItem): RootNode;
|
|
60
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { InputDefinition } from '../body/control/InputDefinition.ts';
|
|
2
|
+
import type { ValueNodeDefinition } from '../model/ValueNodeDefinition.ts';
|
|
3
|
+
import type { BaseNode, BaseNodeState } from './BaseNode.ts';
|
|
4
|
+
import type { RootNode } from './RootNode.ts';
|
|
5
|
+
import type { GeneralParentNode } from './hierarchy.ts';
|
|
6
|
+
export interface StringNodeState extends BaseNodeState {
|
|
7
|
+
get children(): null;
|
|
8
|
+
get valueOptions(): null;
|
|
9
|
+
/**
|
|
10
|
+
* Reflects the current value of a {@link StringNode}. This value may be
|
|
11
|
+
* populated when a form is loaded, and it may be updated by certain
|
|
12
|
+
* computations defined by the form. It may also be updated by a client, using
|
|
13
|
+
* the {@link StringNode.setValue} method.
|
|
14
|
+
*/
|
|
15
|
+
get value(): string;
|
|
16
|
+
}
|
|
17
|
+
export interface StringDefinition extends ValueNodeDefinition {
|
|
18
|
+
readonly bodyElement: InputDefinition | null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A node which can be assigned a string/text value. A string node **MAY**
|
|
22
|
+
* correspond to form field defined as an XForms `<input>`, which a user-facing
|
|
23
|
+
* client would likely present for a user to fill. It may not correspond to an
|
|
24
|
+
* `<input>`, or necessarily have any presentational implications for a client
|
|
25
|
+
* (for instance if the node is bound to an XForms `calculate` expression).
|
|
26
|
+
*/
|
|
27
|
+
export interface StringNode extends BaseNode {
|
|
28
|
+
readonly nodeType: 'string';
|
|
29
|
+
readonly definition: StringDefinition;
|
|
30
|
+
readonly root: RootNode;
|
|
31
|
+
readonly parent: GeneralParentNode;
|
|
32
|
+
readonly currentState: StringNodeState;
|
|
33
|
+
/**
|
|
34
|
+
* For use by a client to update the value of a string node.
|
|
35
|
+
*
|
|
36
|
+
* @todo [how] should we express write restrictions to a client? E.g. what
|
|
37
|
+
* happens when a string node is readonly, and a client attempts to call this
|
|
38
|
+
* method?
|
|
39
|
+
*/
|
|
40
|
+
setValue(value: string): RootNode;
|
|
41
|
+
}
|