@getodk/xforms-engine 0.6.0 → 0.8.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/dist/client/BaseNode.d.ts +4 -4
- package/dist/client/BaseValueNode.d.ts +7 -3
- package/dist/client/RootNode.d.ts +20 -16
- package/dist/client/UploadNode.d.ts +53 -0
- package/dist/client/attachments/InstanceAttachmentMeta.d.ts +8 -0
- package/dist/client/attachments/InstanceAttachmentsConfig.d.ts +8 -0
- package/dist/client/constants.d.ts +11 -12
- package/dist/client/form/CreateFormInstance.d.ts +14 -0
- package/dist/client/form/EditFormInstance.d.ts +62 -0
- package/dist/client/form/FormInstance.d.ts +104 -0
- package/dist/client/form/FormInstanceConfig.d.ts +19 -0
- package/dist/client/form/FormResource.d.ts +1 -0
- package/dist/client/form/LoadForm.d.ts +79 -0
- package/dist/client/form/LoadFormResult.d.ts +67 -0
- package/dist/client/form/RestoreFormInstance.d.ts +8 -0
- package/dist/client/hierarchy.d.ts +4 -5
- package/dist/client/index.d.ts +40 -11
- package/dist/client/node-types.d.ts +2 -3
- package/dist/client/repeat/BaseRepeatRangeNode.d.ts +3 -4
- package/dist/client/repeat/RepeatInstanceNode.d.ts +4 -5
- package/dist/client/repeat/RepeatRangeControlledNode.d.ts +2 -2
- package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +2 -2
- package/dist/client/resources.d.ts +1 -1
- package/dist/client/serialization/InstanceData.d.ts +14 -0
- package/dist/client/serialization/InstanceFile.d.ts +6 -0
- package/dist/client/serialization/InstancePayload.d.ts +93 -0
- package/dist/client/serialization/InstancePayloadOptions.d.ts +24 -0
- package/dist/client/serialization/InstanceState.d.ts +12 -0
- package/dist/client/submission/{SubmissionDefinition.d.ts → SubmissionMeta.d.ts} +1 -1
- package/dist/entrypoints/FormInstance.d.ts +20 -0
- package/dist/entrypoints/FormResult/BaseFormResult.d.ts +22 -0
- package/dist/entrypoints/FormResult/BaseInstantiableFormResult.d.ts +25 -0
- package/dist/entrypoints/FormResult/FormFailureResult.d.ts +17 -0
- package/dist/entrypoints/FormResult/FormSuccessResult.d.ts +15 -0
- package/dist/entrypoints/FormResult/FormWarningResult.d.ts +15 -0
- package/dist/entrypoints/createInstance.d.ts +9 -0
- package/dist/entrypoints/editInstance.d.ts +9 -0
- package/dist/entrypoints/index.d.ts +4 -0
- package/dist/entrypoints/loadForm.d.ts +4 -0
- package/dist/entrypoints/restoreInstance.d.ts +9 -0
- package/dist/error/LoadFormFailureError.d.ts +9 -0
- package/dist/error/MalformedInstanceDataError.d.ts +3 -0
- package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +22 -0
- package/dist/error/UploadValueTypeError.d.ts +8 -0
- package/dist/index.d.ts +2 -33
- package/dist/index.js +8280 -6779
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +6 -5
- package/dist/instance/InputControl.d.ts +5 -4
- package/dist/instance/ModelValue.d.ts +5 -4
- package/dist/instance/Note.d.ts +4 -3
- package/dist/instance/PrimaryInstance.d.ts +34 -8
- package/dist/instance/RangeControl.d.ts +5 -4
- package/dist/instance/RankControl.d.ts +6 -5
- package/dist/instance/Root.d.ts +7 -9
- package/dist/instance/SelectControl.d.ts +4 -3
- package/dist/instance/Subtree.d.ts +6 -5
- package/dist/instance/TriggerControl.d.ts +4 -3
- package/dist/instance/UploadControl.d.ts +58 -0
- package/dist/instance/abstract/DescendantNode.d.ts +10 -1
- package/dist/instance/abstract/InstanceNode.d.ts +7 -4
- package/dist/instance/abstract/ValueNode.d.ts +7 -5
- package/dist/instance/attachments/InstanceAttachment.d.ts +42 -0
- package/dist/instance/attachments/InstanceAttachmentsState.d.ts +9 -0
- package/dist/instance/children/DescendantNodeInitOptions.d.ts +32 -0
- package/dist/instance/{children.d.ts → children/buildChildren.d.ts} +1 -1
- package/dist/instance/children/childrenInitOptions.d.ts +9 -0
- package/dist/instance/children/normalizeChildInitOptions.d.ts +2 -0
- package/dist/instance/hierarchy.d.ts +6 -7
- package/dist/instance/input/InitialInstanceState.d.ts +13 -0
- package/dist/instance/input/InstanceAttachmentMap.d.ts +19 -0
- package/dist/instance/internal-api/InstanceAttachmentContext.d.ts +19 -0
- package/dist/instance/internal-api/InstanceConfig.d.ts +4 -9
- package/dist/instance/internal-api/InstanceValueContext.d.ts +8 -1
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableInstance.d.ts +16 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.d.ts +32 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +18 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +13 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableValueNode.d.ts +21 -0
- package/dist/instance/repeat/BaseRepeatRange.d.ts +10 -8
- package/dist/instance/repeat/RepeatInstance.d.ts +10 -7
- package/dist/instance/repeat/RepeatRangeControlled.d.ts +27 -3
- package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +4 -3
- package/dist/instance/resource.d.ts +5 -1
- package/dist/integration/xpath/EngineXPathEvaluator.d.ts +2 -2
- package/dist/integration/xpath/adapter/kind.d.ts +4 -10
- package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +4 -5
- package/dist/integration/xpath/static-dom/StaticDocument.d.ts +13 -10
- package/dist/integration/xpath/static-dom/StaticElement.d.ts +21 -22
- package/dist/integration/xpath/static-dom/StaticNode.d.ts +1 -1
- package/dist/integration/xpath/static-dom/StaticParentNode.d.ts +13 -0
- package/dist/integration/xpath/static-dom/staticNodeName.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createNodeRangeInstanceState.d.ts +4 -0
- package/dist/lib/client-reactivity/instance-state/createParentNodeInstanceState.d.ts +4 -0
- package/dist/lib/client-reactivity/instance-state/createPrimaryInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createRootInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +6 -0
- package/dist/lib/client-reactivity/instance-state/createValueNodeInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/prepareInstancePayload.d.ts +8 -0
- package/dist/lib/names/UnprefixedXFormsName.d.ts +4 -0
- package/dist/lib/reactivity/createInstanceAttachment.d.ts +8 -0
- package/dist/lib/reactivity/createInstanceValueState.d.ts +2 -27
- package/dist/lib/resource-helpers.d.ts +2 -0
- package/dist/parse/XFormDOM.d.ts +1 -1
- package/dist/parse/body/BodyDefinition.d.ts +2 -1
- package/dist/parse/body/control/UploadControlDefinition.d.ts +2 -0
- package/dist/parse/model/BindDefinition.d.ts +1 -1
- package/dist/parse/model/BindTypeDefinition.d.ts +2 -7
- package/dist/parse/model/ItextTranslationsDefinition.d.ts +18 -0
- package/dist/parse/model/LeafNodeDefinition.d.ts +4 -5
- package/dist/parse/model/ModelBindMap.d.ts +1 -1
- package/dist/parse/model/ModelDefinition.d.ts +9 -2
- package/dist/parse/model/NodeDefinition.d.ts +18 -30
- package/dist/parse/model/NoteNodeDefinition.d.ts +3 -2
- package/dist/parse/model/RangeNodeDefinition.d.ts +2 -1
- package/dist/parse/model/RepeatDefinition.d.ts +62 -0
- package/dist/parse/model/RootAttributeDefinition.d.ts +1 -4
- package/dist/parse/model/RootAttributeMap.d.ts +2 -1
- package/dist/parse/model/RootDefinition.d.ts +7 -8
- package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +15 -2
- package/dist/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.d.ts +5 -0
- package/dist/parse/model/SecondaryInstance/defineSecondaryInstance.d.ts +5 -0
- package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +1 -7
- package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/{FormSubmissionDefinition.d.ts → SubmissionDefinition.d.ts} +2 -2
- package/dist/parse/model/SubtreeDefinition.d.ts +4 -5
- package/dist/parse/model/nodeDefinitionMap.d.ts +5 -0
- package/dist/parse/shared/parseInstanceXML.d.ts +21 -0
- package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +4 -21
- package/dist/solid.js +8251 -6751
- package/dist/solid.js.map +1 -1
- package/package.json +15 -14
- package/src/client/BaseNode.ts +4 -4
- package/src/client/BaseValueNode.ts +7 -3
- package/src/client/RootNode.ts +32 -19
- package/src/client/UploadNode.ts +78 -0
- package/src/client/attachments/InstanceAttachmentMeta.ts +10 -0
- package/src/client/attachments/InstanceAttachmentsConfig.ts +13 -0
- package/src/client/constants.ts +12 -14
- package/src/client/form/CreateFormInstance.ts +19 -0
- package/src/client/form/EditFormInstance.ts +93 -0
- package/src/client/form/FormInstance.ts +114 -0
- package/src/client/form/FormInstanceConfig.ts +21 -0
- package/src/client/form/FormResource.ts +1 -0
- package/src/client/form/LoadForm.ts +92 -0
- package/src/client/form/LoadFormResult.ts +103 -0
- package/src/client/form/RestoreFormInstance.ts +14 -0
- package/src/client/hierarchy.ts +5 -8
- package/src/client/index.ts +49 -29
- package/src/client/node-types.ts +3 -8
- package/src/client/repeat/BaseRepeatRangeNode.ts +3 -4
- package/src/client/repeat/RepeatInstanceNode.ts +4 -8
- package/src/client/repeat/RepeatRangeControlledNode.ts +2 -2
- package/src/client/repeat/RepeatRangeUncontrolledNode.ts +2 -2
- package/src/client/resources.ts +2 -2
- package/src/client/serialization/InstanceData.ts +24 -0
- package/src/client/serialization/InstanceFile.ts +9 -0
- package/src/client/serialization/InstancePayload.ts +126 -0
- package/src/client/serialization/InstancePayloadOptions.ts +29 -0
- package/src/client/serialization/InstanceState.ts +14 -0
- package/src/client/submission/{SubmissionDefinition.ts → SubmissionMeta.ts} +1 -1
- package/src/entrypoints/FormInstance.ts +56 -0
- package/src/entrypoints/FormResult/BaseFormResult.ts +40 -0
- package/src/entrypoints/FormResult/BaseInstantiableFormResult.ts +109 -0
- package/src/entrypoints/FormResult/FormFailureResult.ts +44 -0
- package/src/entrypoints/FormResult/FormSuccessResult.ts +25 -0
- package/src/entrypoints/FormResult/FormWarningResult.ts +25 -0
- package/src/entrypoints/createInstance.ts +23 -0
- package/src/entrypoints/editInstance.ts +24 -0
- package/src/entrypoints/index.ts +4 -0
- package/src/entrypoints/loadForm.ts +154 -0
- package/src/entrypoints/restoreInstance.ts +27 -0
- package/src/error/LoadFormFailureError.ts +114 -0
- package/src/error/MalformedInstanceDataError.ts +3 -0
- package/src/error/TemplatedNodeAttributeSerializationError.ts +24 -0
- package/src/error/UploadValueTypeError.ts +13 -0
- package/src/index.ts +2 -46
- package/src/instance/Group.ts +16 -15
- package/src/instance/InputControl.ts +17 -11
- package/src/instance/ModelValue.ts +17 -11
- package/src/instance/Note.ts +10 -9
- package/src/instance/PrimaryInstance.ts +68 -31
- package/src/instance/RangeControl.ts +17 -11
- package/src/instance/RankControl.ts +28 -19
- package/src/instance/Root.ts +20 -31
- package/src/instance/SelectControl.ts +21 -12
- package/src/instance/Subtree.ts +16 -15
- package/src/instance/TriggerControl.ts +21 -12
- package/src/instance/UploadControl.ts +184 -0
- package/src/instance/abstract/DescendantNode.ts +12 -2
- package/src/instance/abstract/InstanceNode.ts +9 -5
- package/src/instance/abstract/ValueNode.ts +11 -13
- package/src/instance/attachments/InstanceAttachment.ts +69 -0
- package/src/instance/attachments/InstanceAttachmentsState.ts +18 -0
- package/src/instance/children/DescendantNodeInitOptions.ts +35 -0
- package/src/instance/{children.ts → children/buildChildren.ts} +57 -53
- package/src/instance/children/childrenInitOptions.ts +117 -0
- package/src/instance/children/normalizeChildInitOptions.ts +332 -0
- package/src/instance/hierarchy.ts +6 -9
- package/src/instance/input/InitialInstanceState.ts +108 -0
- package/src/instance/input/InstanceAttachmentMap.ts +154 -0
- package/src/instance/internal-api/InstanceAttachmentContext.ts +20 -0
- package/src/instance/internal-api/InstanceConfig.ts +6 -10
- package/src/instance/internal-api/InstanceValueContext.ts +9 -1
- package/src/instance/internal-api/serialization/ClientReactiveSerializableInstance.ts +22 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.ts +43 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +26 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +24 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts +28 -0
- package/src/instance/repeat/BaseRepeatRange.ts +19 -24
- package/src/instance/repeat/RepeatInstance.ts +26 -19
- package/src/instance/repeat/RepeatRangeControlled.ts +90 -17
- package/src/instance/repeat/RepeatRangeUncontrolled.ts +10 -9
- package/src/instance/resource.ts +14 -1
- package/src/integration/xpath/EngineXPathEvaluator.ts +2 -2
- package/src/integration/xpath/adapter/kind.ts +1 -28
- package/src/integration/xpath/adapter/traversal.ts +2 -2
- package/src/integration/xpath/static-dom/StaticAttribute.ts +6 -5
- package/src/integration/xpath/static-dom/StaticDocument.ts +17 -16
- package/src/integration/xpath/static-dom/StaticElement.ts +196 -50
- package/src/integration/xpath/static-dom/StaticNode.ts +1 -1
- package/src/integration/xpath/static-dom/StaticParentNode.ts +22 -0
- package/src/integration/xpath/static-dom/staticNodeName.ts +20 -0
- package/src/lib/client-reactivity/instance-state/createNodeRangeInstanceState.ts +17 -0
- package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +22 -0
- package/src/lib/client-reactivity/instance-state/createPrimaryInstanceState.ts +12 -0
- package/src/lib/client-reactivity/{submission/createRootSubmissionState.ts → instance-state/createRootInstanceState.ts} +4 -4
- package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +31 -0
- package/src/lib/client-reactivity/instance-state/createValueNodeInstanceState.ts +21 -0
- package/src/lib/client-reactivity/instance-state/prepareInstancePayload.ts +237 -0
- package/src/lib/names/UnprefixedXFormsName.ts +12 -0
- package/src/lib/reactivity/createInstanceAttachment.ts +212 -0
- package/src/lib/reactivity/createInstanceValueState.ts +27 -51
- package/src/lib/resource-helpers.ts +33 -0
- package/src/parse/XFormDOM.ts +1 -3
- package/src/parse/body/BodyDefinition.ts +4 -0
- package/src/parse/body/control/UploadControlDefinition.ts +42 -0
- package/src/parse/model/BindDefinition.ts +1 -1
- package/src/parse/model/BindTypeDefinition.ts +68 -26
- package/src/parse/model/ItextTranslationsDefinition.ts +79 -0
- package/src/parse/model/LeafNodeDefinition.ts +3 -5
- package/src/parse/model/ModelBindMap.ts +0 -5
- package/src/parse/model/ModelDefinition.ts +36 -3
- package/src/parse/model/NodeDefinition.ts +19 -45
- package/src/parse/model/NoteNodeDefinition.ts +4 -3
- package/src/parse/model/RangeNodeDefinition.ts +3 -2
- package/src/parse/model/RepeatDefinition.ts +382 -0
- package/src/parse/model/RootAttributeDefinition.ts +6 -7
- package/src/parse/model/RootAttributeMap.ts +15 -10
- package/src/parse/model/RootDefinition.ts +17 -19
- package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +23 -2
- package/src/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.ts +14 -0
- package/src/parse/model/SecondaryInstance/defineSecondaryInstance.ts +32 -0
- package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +3 -24
- package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +33 -86
- package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.ts +1 -30
- package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +64 -137
- package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +9 -7
- package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +1 -1
- package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +7 -7
- package/src/parse/model/{FormSubmissionDefinition.ts → SubmissionDefinition.ts} +2 -2
- package/src/parse/model/SubtreeDefinition.ts +4 -5
- package/src/parse/model/nodeDefinitionMap.ts +34 -0
- package/src/parse/shared/parseInstanceXML.ts +79 -0
- package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +45 -130
- package/dist/client/EngineConfig.d.ts +0 -79
- package/dist/client/submission/SubmissionData.d.ts +0 -7
- package/dist/client/submission/SubmissionInstanceFile.d.ts +0 -6
- package/dist/client/submission/SubmissionOptions.d.ts +0 -23
- package/dist/client/submission/SubmissionResult.d.ts +0 -91
- package/dist/client/submission/SubmissionState.d.ts +0 -12
- package/dist/client/unsupported/UnsupportedControlNode.d.ts +0 -30
- package/dist/client/unsupported/UploadNode.d.ts +0 -9
- package/dist/instance/abstract/UnsupportedControl.d.ts +0 -54
- package/dist/instance/index.d.ts +0 -8
- package/dist/instance/internal-api/ValueContext.d.ts +0 -23
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +0 -14
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +0 -32
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +0 -19
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +0 -18
- package/dist/instance/unsupported/UploadControl.d.ts +0 -6
- package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +0 -4
- package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +0 -4
- package/dist/lib/client-reactivity/submission/createRootSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +0 -8
- package/dist/lib/reactivity/createValueState.d.ts +0 -40
- package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +0 -4
- package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +0 -9
- package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +0 -8
- package/dist/parse/model/RepeatInstanceDefinition.d.ts +0 -17
- package/dist/parse/model/RepeatRangeDefinition.d.ts +0 -32
- package/dist/parse/model/RepeatTemplateDefinition.d.ts +0 -31
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +0 -4
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +0 -7
- package/src/client/EngineConfig.ts +0 -84
- package/src/client/submission/SubmissionData.ts +0 -12
- package/src/client/submission/SubmissionInstanceFile.ts +0 -9
- package/src/client/submission/SubmissionOptions.ts +0 -28
- package/src/client/submission/SubmissionResult.ts +0 -124
- package/src/client/submission/SubmissionState.ts +0 -14
- package/src/client/unsupported/UnsupportedControlNode.ts +0 -36
- package/src/client/unsupported/UploadNode.ts +0 -14
- package/src/instance/abstract/UnsupportedControl.ts +0 -175
- package/src/instance/index.ts +0 -55
- package/src/instance/internal-api/ValueContext.ts +0 -28
- package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +0 -20
- package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +0 -43
- package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +0 -26
- package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +0 -24
- package/src/instance/unsupported/UploadControl.ts +0 -9
- package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +0 -12
- package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +0 -20
- package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +0 -17
- package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +0 -22
- package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +0 -21
- package/src/lib/client-reactivity/submission/prepareSubmission.ts +0 -172
- package/src/lib/reactivity/createValueState.ts +0 -200
- package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +0 -4
- package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +0 -42
- package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +0 -31
- package/src/parse/model/RepeatInstanceDefinition.ts +0 -38
- package/src/parse/model/RepeatRangeDefinition.ts +0 -98
- package/src/parse/model/RepeatTemplateDefinition.ts +0 -149
- package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +0 -4
- package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +0 -12
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OPENROSA_XFORMS_NAMESPACE_URI,
|
|
3
|
+
XFORMS_NAMESPACE_URI,
|
|
4
|
+
} from '@getodk/common/constants/xmlns.ts';
|
|
5
|
+
import type { GroupDefinition } from '../../client/GroupNode.ts';
|
|
6
|
+
import type { SubtreeDefinition } from '../../client/SubtreeNode.ts';
|
|
7
|
+
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
8
|
+
import { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
|
|
9
|
+
import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
10
|
+
import { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
11
|
+
import type { NamespaceURL } from '../../lib/names/NamespaceURL.ts';
|
|
12
|
+
import type { QualifiedName } from '../../lib/names/QualifiedName.ts';
|
|
13
|
+
import { LeafNodeDefinition } from '../../parse/model/LeafNodeDefinition.ts';
|
|
14
|
+
import type { SubtreeDefinition as ModelSubtreeDefinition } from '../../parse/model/SubtreeDefinition.ts';
|
|
15
|
+
import type { XFormDOM } from '../../parse/XFormDOM.ts';
|
|
16
|
+
import type { Group } from '../Group.ts';
|
|
17
|
+
import type { GeneralParentNode } from '../hierarchy.ts';
|
|
18
|
+
import type { PrimaryInstance } from '../PrimaryInstance.ts';
|
|
19
|
+
import type { Root } from '../Root.ts';
|
|
20
|
+
import type { Subtree } from '../Subtree.ts';
|
|
21
|
+
import type { ChildrenInitOptions } from './childrenInitOptions.ts';
|
|
22
|
+
import type { DescendantNodeInitOptions } from './DescendantNodeInitOptions.ts';
|
|
23
|
+
|
|
24
|
+
const META_LOCAL_NAME = 'meta';
|
|
25
|
+
const INSTANCE_ID_LOCAL_NAME = 'instanceID';
|
|
26
|
+
const DEPRECATED_ID_LOCAL_NAME = 'deprecatedID';
|
|
27
|
+
|
|
28
|
+
type MetaLocalName = typeof META_LOCAL_NAME;
|
|
29
|
+
|
|
30
|
+
const META_NAMESPACE_URIS = [OPENROSA_XFORMS_NAMESPACE_URI, XFORMS_NAMESPACE_URI] as const;
|
|
31
|
+
|
|
32
|
+
type MetaNamespaceURIValue = (typeof META_NAMESPACE_URIS)[number];
|
|
33
|
+
|
|
34
|
+
interface MetaNamespaceURI extends NamespaceURL {
|
|
35
|
+
readonly href: MetaNamespaceURIValue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface MetaNamespacedName extends QualifiedName {
|
|
39
|
+
readonly namespaceURI: MetaNamespaceURI;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const isMetaNamespacedName = (
|
|
43
|
+
qualifiedName: QualifiedName
|
|
44
|
+
): qualifiedName is MetaNamespacedName => {
|
|
45
|
+
const namespaceURI = qualifiedName.namespaceURI?.href;
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
namespaceURI != null && META_NAMESPACE_URIS.includes(namespaceURI as MetaNamespaceURIValue)
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
interface MetaName extends MetaNamespacedName {
|
|
53
|
+
readonly localName: MetaLocalName;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const isMetaName = (qualifiedName: QualifiedName): qualifiedName is MetaName => {
|
|
57
|
+
return isMetaNamespacedName(qualifiedName) && qualifiedName.localName === META_LOCAL_NAME;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const isDirectRootDescendant = (parent: GeneralParentNode) => {
|
|
61
|
+
return parent.parent === parent.root;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
interface BaseMetaDefinition {
|
|
65
|
+
readonly qualifiedName: MetaName;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const isBaseMetaDefinition = <T extends ModelSubtreeDefinition>(
|
|
69
|
+
definition: T
|
|
70
|
+
): definition is BaseMetaDefinition & T => {
|
|
71
|
+
return isMetaName(definition.qualifiedName);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
interface MetaSubtreeDefinition extends SubtreeDefinition {
|
|
75
|
+
readonly qualifiedName: MetaName;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface MetaSubtree extends Subtree {
|
|
79
|
+
readonly parent: Root;
|
|
80
|
+
readonly definition: MetaSubtreeDefinition;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface MetaGroupDefinition extends GroupDefinition {
|
|
84
|
+
readonly qualifiedName: MetaName;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface MetaGroup extends Group {
|
|
88
|
+
readonly parent: Root;
|
|
89
|
+
readonly definition: MetaGroupDefinition;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
type MetaSubroot = MetaGroup | MetaSubtree;
|
|
93
|
+
|
|
94
|
+
interface MetaSubrootInitOptions extends ChildrenInitOptions {
|
|
95
|
+
readonly parent: MetaGroup | MetaSubtree;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const isMetaSubroot = (options: ChildrenInitOptions): options is MetaSubrootInitOptions => {
|
|
99
|
+
const { nodeType } = options.parent;
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
(nodeType === 'subtree' || nodeType === 'group') &&
|
|
103
|
+
isDirectRootDescendant(options.parent) &&
|
|
104
|
+
isBaseMetaDefinition(options.parent.definition)
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
interface EditModeInstance extends PrimaryInstance {
|
|
109
|
+
readonly initializationMode: 'edit';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const isEditModeInstance = (
|
|
113
|
+
primaryInstance: PrimaryInstance
|
|
114
|
+
): primaryInstance is EditModeInstance => {
|
|
115
|
+
return primaryInstance.initializationMode === 'edit';
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
interface EditModeInstanceDescendant {
|
|
119
|
+
readonly rootDocument: EditModeInstance;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
type EditModeMetaSubroot = EditModeInstanceDescendant & MetaSubroot;
|
|
123
|
+
|
|
124
|
+
interface EditModeMetaSubrootInitOptions extends MetaSubrootInitOptions {
|
|
125
|
+
readonly parent: EditModeMetaSubroot;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const isEditModeMetaSubroot = (
|
|
129
|
+
subroot: MetaSubrootInitOptions
|
|
130
|
+
): subroot is EditModeMetaSubrootInitOptions => {
|
|
131
|
+
return isEditModeInstance(subroot.parent.rootDocument);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
interface LeafNodeInitOptions extends DescendantNodeInitOptions {
|
|
135
|
+
readonly instanceNodes: readonly [StaticLeafElement];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const isLeafNodeInitOptions = (
|
|
139
|
+
options: DescendantNodeInitOptions
|
|
140
|
+
): options is LeafNodeInitOptions => {
|
|
141
|
+
const { instanceNodes } = options;
|
|
142
|
+
const [instanceNode, ...rest] = instanceNodes;
|
|
143
|
+
|
|
144
|
+
return instanceNode != null && rest.length === 0 && instanceNode.isLeafElement();
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
type MetaLeafChildEntry = readonly [index: number, child: LeafNodeInitOptions];
|
|
148
|
+
|
|
149
|
+
const findMetaLeafChild = (
|
|
150
|
+
subroot: MetaSubrootInitOptions,
|
|
151
|
+
localName: string
|
|
152
|
+
): MetaLeafChildEntry | null => {
|
|
153
|
+
const metaName = subroot.parent.definition.qualifiedName satisfies MetaName;
|
|
154
|
+
const namespaceURI = metaName.namespaceURI.href satisfies MetaNamespaceURIValue;
|
|
155
|
+
|
|
156
|
+
const result = Array.from(subroot.children.entries()).find(
|
|
157
|
+
(entry): entry is [number, LeafNodeInitOptions] => {
|
|
158
|
+
const [, child] = entry;
|
|
159
|
+
|
|
160
|
+
if (!isLeafNodeInitOptions(child)) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const [instanceNode] = child.instanceNodes;
|
|
165
|
+
const { qualifiedName } = instanceNode;
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
qualifiedName.localName === localName && qualifiedName.namespaceURI?.href === namespaceURI
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
return result ?? null;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const getInstanceIDValue = (subroot: MetaSubrootInitOptions): string | null => {
|
|
177
|
+
const [, child = null] = findMetaLeafChild(subroot, INSTANCE_ID_LOCAL_NAME) ?? [];
|
|
178
|
+
|
|
179
|
+
if (child == null) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const [instanceIDNode] = child.instanceNodes;
|
|
184
|
+
|
|
185
|
+
return instanceIDNode.value satisfies string;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
type AssertStaticLeafElement = (element: StaticElement) => asserts element is StaticLeafElement;
|
|
189
|
+
|
|
190
|
+
const assertStaticLeafElement: AssertStaticLeafElement = (element) => {
|
|
191
|
+
if (!element.isLeafElement()) {
|
|
192
|
+
throw new ErrorProductionDesignPendingError(
|
|
193
|
+
`Expected a leaf element, got a non-leaf element at nodeset: ${element.nodeset}`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @todo this name and signature are general, for the same reasons as the TODO
|
|
200
|
+
* on {@link populateDeprecatedID}.
|
|
201
|
+
*/
|
|
202
|
+
const buildMetaValueElement = (
|
|
203
|
+
subroot: MetaSubrootInitOptions,
|
|
204
|
+
localName: string,
|
|
205
|
+
value: string
|
|
206
|
+
): StaticLeafElement => {
|
|
207
|
+
const { qualifiedName, nodeset } = subroot.parent.definition;
|
|
208
|
+
const { namespaceURI, prefix } = qualifiedName;
|
|
209
|
+
const { root } = new StaticDocument({
|
|
210
|
+
documentRoot: {
|
|
211
|
+
name: {
|
|
212
|
+
namespaceURI,
|
|
213
|
+
prefix,
|
|
214
|
+
localName,
|
|
215
|
+
},
|
|
216
|
+
children: [value],
|
|
217
|
+
},
|
|
218
|
+
nodesetPrefix: nodeset,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
assertStaticLeafElement(root);
|
|
222
|
+
|
|
223
|
+
return root;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const buildDeprecatedIDDefinition = (
|
|
227
|
+
subroot: EditModeMetaSubrootInitOptions,
|
|
228
|
+
instanceNode: StaticLeafElement
|
|
229
|
+
): LeafNodeDefinition => {
|
|
230
|
+
const nodeset = instanceNode.nodeset;
|
|
231
|
+
const bind = subroot.model.binds.getOrCreateBindDefinition(nodeset);
|
|
232
|
+
|
|
233
|
+
return new LeafNodeDefinition(subroot.parent.definition, bind, null, instanceNode);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const buildDeprecatedID = (
|
|
237
|
+
subroot: EditModeMetaSubrootInitOptions,
|
|
238
|
+
value: string
|
|
239
|
+
): LeafNodeInitOptions => {
|
|
240
|
+
const instanceNode = buildMetaValueElement(subroot, DEPRECATED_ID_LOCAL_NAME, value);
|
|
241
|
+
const definition = buildDeprecatedIDDefinition(subroot, instanceNode);
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
childNodeset: instanceNode.nodeset,
|
|
245
|
+
definition,
|
|
246
|
+
instanceNodes: [instanceNode],
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const updateDeprecatedID = (
|
|
251
|
+
subroot: EditModeMetaSubrootInitOptions,
|
|
252
|
+
child: LeafNodeInitOptions,
|
|
253
|
+
value: string
|
|
254
|
+
): LeafNodeInitOptions => {
|
|
255
|
+
const instanceNode = buildMetaValueElement(subroot, DEPRECATED_ID_LOCAL_NAME, value);
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
childNodeset: child.childNodeset,
|
|
259
|
+
definition: child.definition,
|
|
260
|
+
instanceNodes: [instanceNode],
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Should be: values.with(index, value)
|
|
266
|
+
*
|
|
267
|
+
* @todo update tsconfig.json `lib` throughout project!
|
|
268
|
+
*/
|
|
269
|
+
const replace = <T>(values: readonly T[], index: number, value: T): readonly T[] => {
|
|
270
|
+
const results = values.slice();
|
|
271
|
+
|
|
272
|
+
results.splice(index, 1, value);
|
|
273
|
+
|
|
274
|
+
return results;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const replaceOrConcat = <T>(values: readonly T[], index: number | null, value: T): readonly T[] => {
|
|
278
|
+
if (index == null) {
|
|
279
|
+
return values.concat(value);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return replace(values, index, value);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @todo Whenever we have bandwidth to start migrating away from DOM usage in
|
|
287
|
+
* {@link XFormDOM}, this is a good place to start for logic equivalent to the
|
|
288
|
+
* hacky normalization for `instanceID`.
|
|
289
|
+
*/
|
|
290
|
+
const populateDeprecatedID = (
|
|
291
|
+
subroot: EditModeMetaSubrootInitOptions
|
|
292
|
+
): EditModeMetaSubrootInitOptions => {
|
|
293
|
+
const value = getInstanceIDValue(subroot);
|
|
294
|
+
|
|
295
|
+
if (value == null) {
|
|
296
|
+
return subroot;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const [index, currentDeprecatedID] = findMetaLeafChild(subroot, DEPRECATED_ID_LOCAL_NAME) ?? [
|
|
300
|
+
null,
|
|
301
|
+
];
|
|
302
|
+
|
|
303
|
+
let deprecatedID: LeafNodeInitOptions;
|
|
304
|
+
|
|
305
|
+
if (currentDeprecatedID == null) {
|
|
306
|
+
deprecatedID = buildDeprecatedID(subroot, value);
|
|
307
|
+
} else {
|
|
308
|
+
deprecatedID = updateDeprecatedID(subroot, currentDeprecatedID, value);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return {
|
|
312
|
+
model: subroot.model,
|
|
313
|
+
parent: subroot.parent,
|
|
314
|
+
children: replaceOrConcat(subroot.children, index, deprecatedID),
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const normalizeMetaSubroot = (subroot: MetaSubrootInitOptions): MetaSubrootInitOptions => {
|
|
319
|
+
if (isEditModeMetaSubroot(subroot)) {
|
|
320
|
+
return populateDeprecatedID(subroot);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return subroot;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
export const normalizeChildInitOptions = (options: ChildrenInitOptions): ChildrenInitOptions => {
|
|
327
|
+
if (isMetaSubroot(options)) {
|
|
328
|
+
return normalizeMetaSubroot(options);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return options;
|
|
332
|
+
};
|
|
@@ -4,6 +4,7 @@ import type { AnyModelValue } from './ModelValue.ts';
|
|
|
4
4
|
import type { AnyNote } from './Note.ts';
|
|
5
5
|
import type { PrimaryInstance } from './PrimaryInstance.ts';
|
|
6
6
|
import type { AnyRangeControl } from './RangeControl.ts';
|
|
7
|
+
import type { RankControl } from './RankControl.ts';
|
|
7
8
|
import type { RepeatInstance } from './repeat/RepeatInstance.ts';
|
|
8
9
|
import type { RepeatRangeControlled } from './repeat/RepeatRangeControlled.ts';
|
|
9
10
|
import type { RepeatRangeUncontrolled } from './repeat/RepeatRangeUncontrolled.ts';
|
|
@@ -11,14 +12,10 @@ import type { Root } from './Root.ts';
|
|
|
11
12
|
import type { SelectControl } from './SelectControl.ts';
|
|
12
13
|
import type { Subtree } from './Subtree.ts';
|
|
13
14
|
import type { TriggerControl } from './TriggerControl.ts';
|
|
14
|
-
import type {
|
|
15
|
-
import type { UploadControl } from './unsupported/UploadControl.ts';
|
|
15
|
+
import type { UploadControl } from './UploadControl.ts';
|
|
16
16
|
|
|
17
17
|
export type RepeatRange = RepeatRangeControlled | RepeatRangeUncontrolled;
|
|
18
18
|
|
|
19
|
-
// prettier-ignore
|
|
20
|
-
export type AnyUnsupportedControl = UploadControl;
|
|
21
|
-
|
|
22
19
|
// prettier-ignore
|
|
23
20
|
export type AnyNode =
|
|
24
21
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
@@ -35,7 +32,7 @@ export type AnyNode =
|
|
|
35
32
|
| RankControl
|
|
36
33
|
| SelectControl
|
|
37
34
|
| TriggerControl
|
|
38
|
-
|
|
|
35
|
+
| UploadControl;
|
|
39
36
|
|
|
40
37
|
// prettier-ignore
|
|
41
38
|
export type AnyParentNode =
|
|
@@ -70,7 +67,7 @@ export type AnyChildNode =
|
|
|
70
67
|
| RankControl
|
|
71
68
|
| SelectControl
|
|
72
69
|
| TriggerControl
|
|
73
|
-
|
|
|
70
|
+
| UploadControl;
|
|
74
71
|
|
|
75
72
|
// prettier-ignore
|
|
76
73
|
export type GeneralChildNode =
|
|
@@ -85,7 +82,7 @@ export type GeneralChildNode =
|
|
|
85
82
|
| RankControl
|
|
86
83
|
| SelectControl
|
|
87
84
|
| TriggerControl
|
|
88
|
-
|
|
|
85
|
+
| UploadControl;
|
|
89
86
|
|
|
90
87
|
// prettier-ignore
|
|
91
88
|
export type AnyValueNode =
|
|
@@ -97,4 +94,4 @@ export type AnyValueNode =
|
|
|
97
94
|
| RankControl
|
|
98
95
|
| SelectControl
|
|
99
96
|
| TriggerControl
|
|
100
|
-
|
|
|
97
|
+
| UploadControl;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { getBlobText } from '@getodk/common/lib/web-compat/blob.ts';
|
|
2
|
+
import { INSTANCE_FILE_NAME } from '../../client/constants.ts';
|
|
3
|
+
import type {
|
|
4
|
+
EditFormInstanceInput,
|
|
5
|
+
ResolvableFormInstanceInput,
|
|
6
|
+
} from '../../client/form/EditFormInstance.ts';
|
|
7
|
+
import type { InstanceData } from '../../client/serialization/InstanceData.ts';
|
|
8
|
+
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
9
|
+
import type { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
|
|
10
|
+
import type { ModelDefinition } from '../../parse/model/ModelDefinition.ts';
|
|
11
|
+
import { parseInstanceXML } from '../../parse/shared/parseInstanceXML.ts';
|
|
12
|
+
import type { XFormDOM } from '../../parse/XFormDOM.ts';
|
|
13
|
+
import { InstanceAttachmentMap } from './InstanceAttachmentMap.ts';
|
|
14
|
+
|
|
15
|
+
export type InitialInstanceStateSources = readonly [InstanceData, ...InstanceData[]];
|
|
16
|
+
|
|
17
|
+
interface InitialInstanceStateOptions {
|
|
18
|
+
readonly instanceXML: string;
|
|
19
|
+
readonly attachments: InstanceAttachmentMap;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const resolveInstanceXML = async (input: ResolvableFormInstanceInput): Promise<string> => {
|
|
23
|
+
const instanceResult = await input.resolveInstance();
|
|
24
|
+
|
|
25
|
+
if (typeof instanceResult === 'string') {
|
|
26
|
+
return instanceResult;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (instanceResult instanceof Blob) {
|
|
30
|
+
return getBlobText(instanceResult);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return instanceResult.text();
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const parseInstanceDocument = (model: ModelDefinition, instanceXML: string): StaticDocument => {
|
|
37
|
+
const doc = parseInstanceXML(model, instanceXML);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Note: this is presently inferred as nullable. Its presence is _currently_
|
|
41
|
+
* enforced by {@link XFormDOM}, though that's definitely not ideal!
|
|
42
|
+
*
|
|
43
|
+
* @todo we would probably benefit from a single parse function responsible
|
|
44
|
+
* for both instance documents (form and input), with all `id` enforcement
|
|
45
|
+
* handled in one place (presence in both cases, matching in case of form +
|
|
46
|
+
* input). We could then also express this at the type level without weird DOM
|
|
47
|
+
* shenanigans in {@link XFormDOM} (which aren't likely to stick around in
|
|
48
|
+
* their current state forever!).
|
|
49
|
+
*/
|
|
50
|
+
const expectedId = model.instance.root.getAttributeValue('id');
|
|
51
|
+
const actualId = doc.root.getAttributeValue('id');
|
|
52
|
+
|
|
53
|
+
if (expectedId !== actualId) {
|
|
54
|
+
throw new ErrorProductionDesignPendingError(
|
|
55
|
+
`Invalid instance input. Expected instance id to be "${expectedId}", got: "${actualId}"`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return doc;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export class InitialInstanceState {
|
|
63
|
+
static async from(
|
|
64
|
+
model: ModelDefinition,
|
|
65
|
+
data: InitialInstanceStateSources
|
|
66
|
+
): Promise<InitialInstanceState> {
|
|
67
|
+
return this.resolve(model, {
|
|
68
|
+
inputType: 'FORM_INSTANCE_INPUT_RESOLVED',
|
|
69
|
+
data,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static async resolve(
|
|
74
|
+
model: ModelDefinition,
|
|
75
|
+
input: EditFormInstanceInput
|
|
76
|
+
): Promise<InitialInstanceState> {
|
|
77
|
+
if (input.inputType === 'FORM_INSTANCE_INPUT_RESOLVED') {
|
|
78
|
+
const { data } = input;
|
|
79
|
+
const [instanceData] = data;
|
|
80
|
+
const instanceFile = instanceData.get(INSTANCE_FILE_NAME);
|
|
81
|
+
const instanceXML = await getBlobText(instanceFile);
|
|
82
|
+
const attachments = InstanceAttachmentMap.from(data);
|
|
83
|
+
|
|
84
|
+
return new this(model, {
|
|
85
|
+
instanceXML,
|
|
86
|
+
attachments,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const [instanceXML, attachments] = await Promise.all([
|
|
91
|
+
resolveInstanceXML(input),
|
|
92
|
+
InstanceAttachmentMap.resolve(input.attachments),
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
return new this(model, {
|
|
96
|
+
instanceXML,
|
|
97
|
+
attachments,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
readonly document: StaticDocument;
|
|
102
|
+
readonly attachments: InstanceAttachmentMap;
|
|
103
|
+
|
|
104
|
+
private constructor(model: ModelDefinition, options: InitialInstanceStateOptions) {
|
|
105
|
+
this.document = parseInstanceDocument(model, options.instanceXML);
|
|
106
|
+
this.attachments = options.attachments;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { getBlobData } from '@getodk/common/lib/web-compat/blob.ts';
|
|
2
|
+
import { INSTANCE_FILE_NAME } from '../../client/constants.ts';
|
|
3
|
+
import type { ResolvableInstanceAttachmentsMap } from '../../client/form/EditFormInstance.ts';
|
|
4
|
+
import { MalformedInstanceDataError } from '../../error/MalformedInstanceDataError.ts';
|
|
5
|
+
import { getResponseContentType } from '../../lib/resource-helpers.ts';
|
|
6
|
+
import type { FetchResourceResponse } from '../resource.ts';
|
|
7
|
+
|
|
8
|
+
type InstanceAttachmentMapSourceEntry = readonly [key: string, value: FormDataEntryValue];
|
|
9
|
+
|
|
10
|
+
interface InstanceAttachmentMapSource {
|
|
11
|
+
entries(): Iterable<InstanceAttachmentMapSourceEntry>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type InstanceAttachmentMapSources = readonly [
|
|
15
|
+
InstanceAttachmentMapSource,
|
|
16
|
+
...InstanceAttachmentMapSource[],
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
const DEFAULT_ATTACHMENT_TYPE = 'application/octet-stream';
|
|
20
|
+
|
|
21
|
+
const resolveContentType = (response: FetchResourceResponse, blob: Blob): string => {
|
|
22
|
+
let result = blob.type;
|
|
23
|
+
|
|
24
|
+
if (result === '') {
|
|
25
|
+
result = getResponseContentType(response) ?? result;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (result === '') {
|
|
29
|
+
return DEFAULT_ATTACHMENT_TYPE;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const resolveInstanceAttachmentFile = async (
|
|
36
|
+
response: FetchResourceResponse,
|
|
37
|
+
fileName: string
|
|
38
|
+
): Promise<File> => {
|
|
39
|
+
const blob = await response.blob();
|
|
40
|
+
const blobData = await getBlobData(blob);
|
|
41
|
+
|
|
42
|
+
return new File([blobData], fileName, {
|
|
43
|
+
type: resolveContentType(response, blob),
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @todo Everything about this is incredibly naive! We should almost certainly
|
|
49
|
+
* do _at least_ the following:
|
|
50
|
+
*
|
|
51
|
+
* - Limit how many attachments we attempt to resolve concurrently
|
|
52
|
+
* - Lazy resolution of large attachments (i.e. probably streaming, maybe range
|
|
53
|
+
* requests, ?)
|
|
54
|
+
*
|
|
55
|
+
* @todo Once lazy resolution is a thing, we will **also** need a clear path
|
|
56
|
+
* from there to eager resolution (i.e. for offline caching: it doesn't make
|
|
57
|
+
* sense to cache a stream in progress, as it won't load the resource once the
|
|
58
|
+
* user actually is offline/lacks network access). This may be something we can
|
|
59
|
+
* evolve gradually!
|
|
60
|
+
*/
|
|
61
|
+
const resolveInstanceAttachmentMapSource = async (
|
|
62
|
+
input: ResolvableInstanceAttachmentsMap
|
|
63
|
+
): Promise<InstanceAttachmentMapSource> => {
|
|
64
|
+
const entries = await Promise.all<InstanceAttachmentMapSourceEntry>(
|
|
65
|
+
Array.from(input.entries()).map(async ([fileName, resolveAttachment]) => {
|
|
66
|
+
const response = await resolveAttachment();
|
|
67
|
+
const value = await resolveInstanceAttachmentFile(response, fileName);
|
|
68
|
+
|
|
69
|
+
return [fileName, value] as const;
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return { entries: () => entries };
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
interface KeyedInstanceDataFile<Key extends string> extends File {
|
|
77
|
+
readonly name: Key;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
type AssertKeyedInstanceDataFile = <Key extends string>(
|
|
81
|
+
key: Key,
|
|
82
|
+
file: File
|
|
83
|
+
) => asserts file is KeyedInstanceDataFile<Key>;
|
|
84
|
+
|
|
85
|
+
const assertKeyedInstanceDataFile: AssertKeyedInstanceDataFile = (key, file) => {
|
|
86
|
+
if (file.name !== key) {
|
|
87
|
+
throw new MalformedInstanceDataError(
|
|
88
|
+
`Unexpected InstanceData file. Expected file name to match key, got key: ${JSON.stringify(key)} and file name: ${JSON.stringify(file.name)}`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
type UnknownInstanceDataEntry = readonly [key: string, value: FormDataEntryValue];
|
|
94
|
+
|
|
95
|
+
type KeyedInstanceDataEntry<Key extends string> = readonly [key: Key, KeyedInstanceDataFile<Key>];
|
|
96
|
+
|
|
97
|
+
type AssertInstanceDataEntry = <Key extends string>(
|
|
98
|
+
entry: UnknownInstanceDataEntry
|
|
99
|
+
) => asserts entry is KeyedInstanceDataEntry<Key>;
|
|
100
|
+
|
|
101
|
+
const assertInstanceDataEntry: AssertInstanceDataEntry = (entry) => {
|
|
102
|
+
const [key, value] = entry;
|
|
103
|
+
|
|
104
|
+
if (!(value instanceof File)) {
|
|
105
|
+
throw new MalformedInstanceDataError(
|
|
106
|
+
`Unexpected non-file attachment in InstanceData for key: ${key}`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
assertKeyedInstanceDataFile(key, value);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export class InstanceAttachmentMap extends Map<string, File> {
|
|
114
|
+
static from(sources: InstanceAttachmentMapSources): InstanceAttachmentMap {
|
|
115
|
+
return new this(sources);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @todo
|
|
120
|
+
* @see {@link resolveInstanceAttachmentMapSource}
|
|
121
|
+
*/
|
|
122
|
+
static async resolve(input: ResolvableInstanceAttachmentsMap): Promise<InstanceAttachmentMap> {
|
|
123
|
+
const source = await resolveInstanceAttachmentMapSource(input);
|
|
124
|
+
|
|
125
|
+
return new this([source]);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private constructor(sources: InstanceAttachmentMapSources) {
|
|
129
|
+
super();
|
|
130
|
+
|
|
131
|
+
for (const source of sources) {
|
|
132
|
+
for (const entry of source.entries()) {
|
|
133
|
+
const [key] = entry;
|
|
134
|
+
|
|
135
|
+
// Skip the instance XML file: it's not an attachment!
|
|
136
|
+
if (key === INSTANCE_FILE_NAME) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (this.has(key)) {
|
|
141
|
+
throw new MalformedInstanceDataError(
|
|
142
|
+
`Unexpected InstanceData entry. Duplicate instance attachment for key: ${JSON.stringify(key)}`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
assertInstanceDataEntry(entry);
|
|
147
|
+
|
|
148
|
+
const [, value] = entry;
|
|
149
|
+
|
|
150
|
+
this.set(key, value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Accessor } from 'solid-js';
|
|
2
|
+
import type { FormNodeID } from '../../client/identity.ts';
|
|
3
|
+
import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
4
|
+
import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
|
|
5
|
+
import type { InstanceAttachmentsState } from '../attachments/InstanceAttachmentsState.ts';
|
|
6
|
+
import type { InstanceConfig } from './InstanceConfig.ts';
|
|
7
|
+
|
|
8
|
+
interface InstanceAttachmentRootDocument {
|
|
9
|
+
readonly attachments: InstanceAttachmentsState;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface InstanceAttachmentContext {
|
|
13
|
+
readonly instanceConfig: InstanceConfig;
|
|
14
|
+
readonly scope: ReactiveScope;
|
|
15
|
+
readonly rootDocument: InstanceAttachmentRootDocument;
|
|
16
|
+
readonly nodeId: FormNodeID;
|
|
17
|
+
readonly instanceNode: StaticLeafElement | null;
|
|
18
|
+
readonly isRelevant: Accessor<boolean>;
|
|
19
|
+
readonly isAttached: Accessor<boolean>;
|
|
20
|
+
}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { InstanceAttachmentFileNameFactory } from '../../client/attachments/InstanceAttachmentsConfig.ts';
|
|
2
|
+
import type { FormInstanceConfig } from '../../client/form/FormInstanceConfig.ts';
|
|
2
3
|
import type { OpaqueReactiveObjectFactory } from '../../client/OpaqueReactiveObjectFactory.ts';
|
|
3
|
-
import type { FetchFormAttachment, FetchResource } from '../../client/resources.ts';
|
|
4
|
-
import type { CreateUniqueId } from '../../lib/unique-id.ts';
|
|
5
4
|
|
|
6
5
|
export interface InstanceConfig {
|
|
7
|
-
readonly stateFactory: OpaqueReactiveObjectFactory;
|
|
8
|
-
readonly fetchFormDefinition: FetchResource;
|
|
9
|
-
readonly fetchFormAttachment: FetchFormAttachment;
|
|
10
|
-
readonly missingResourceBehavior: MissingResourceBehavior;
|
|
11
|
-
|
|
12
6
|
/**
|
|
13
|
-
*
|
|
7
|
+
* @see {@link FormInstanceConfig.stateFactory}
|
|
14
8
|
*/
|
|
15
|
-
readonly
|
|
9
|
+
readonly clientStateFactory: OpaqueReactiveObjectFactory;
|
|
10
|
+
|
|
11
|
+
readonly computeAttachmentName: InstanceAttachmentFileNameFactory;
|
|
16
12
|
}
|