@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,14 @@
|
|
|
1
|
+
import type { RootNode } from '../RootNode.ts';
|
|
2
|
+
|
|
3
|
+
export interface InstanceState {
|
|
4
|
+
/**
|
|
5
|
+
* Represents the serialized XML state of a given node. The value produced in
|
|
6
|
+
* {@link RootNode.instanceState} is the same serialization which will be
|
|
7
|
+
* produced for a complete instance.
|
|
8
|
+
*
|
|
9
|
+
* @todo Note that this particular aspect of the design doesn't yet address
|
|
10
|
+
* production of unique file names. As such, this may change as we introduce
|
|
11
|
+
* affected data types (and their supporting nodes).
|
|
12
|
+
*/
|
|
13
|
+
get instanceXML(): string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { identity } from '@getodk/common/lib/identity.ts';
|
|
2
|
+
import type {
|
|
3
|
+
FormInstance as ClientFormInstance,
|
|
4
|
+
FormInstanceInitializationMode,
|
|
5
|
+
} from '../client/form/FormInstance.ts';
|
|
6
|
+
import type { FormInstanceConfig } from '../client/index.ts';
|
|
7
|
+
import type { InstanceConfig } from '../instance/internal-api/InstanceConfig.ts';
|
|
8
|
+
import type {
|
|
9
|
+
BasePrimaryInstanceOptions,
|
|
10
|
+
PrimaryInstanceInitialState,
|
|
11
|
+
PrimaryInstanceOptions,
|
|
12
|
+
} from '../instance/PrimaryInstance.ts';
|
|
13
|
+
import { PrimaryInstance } from '../instance/PrimaryInstance.ts';
|
|
14
|
+
import type { Root } from '../instance/Root.ts';
|
|
15
|
+
import type { FormSuccessResult } from './FormResult/FormSuccessResult.ts';
|
|
16
|
+
import type { FormWarningResult } from './FormResult/FormWarningResult.ts';
|
|
17
|
+
|
|
18
|
+
// prettier-ignore
|
|
19
|
+
export type InstantiableFormResult =
|
|
20
|
+
| FormSuccessResult
|
|
21
|
+
| FormWarningResult;
|
|
22
|
+
|
|
23
|
+
interface FormInstanceOptions<Mode extends FormInstanceInitializationMode> {
|
|
24
|
+
readonly mode: Mode;
|
|
25
|
+
readonly initialState: PrimaryInstanceInitialState<Mode>;
|
|
26
|
+
readonly instanceOptions: BasePrimaryInstanceOptions;
|
|
27
|
+
readonly instanceConfig: FormInstanceConfig;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class FormInstance<Mode extends FormInstanceInitializationMode>
|
|
31
|
+
implements ClientFormInstance<Mode>
|
|
32
|
+
{
|
|
33
|
+
readonly mode: Mode;
|
|
34
|
+
readonly root: Root;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
readonly formResult: InstantiableFormResult,
|
|
38
|
+
options: FormInstanceOptions<Mode>
|
|
39
|
+
) {
|
|
40
|
+
const { mode, initialState, instanceConfig } = options;
|
|
41
|
+
const config: InstanceConfig = {
|
|
42
|
+
clientStateFactory: instanceConfig.stateFactory ?? identity,
|
|
43
|
+
computeAttachmentName: instanceConfig.instanceAttachments?.fileNameFactory ?? (() => null),
|
|
44
|
+
};
|
|
45
|
+
const primaryInstanceOptions: PrimaryInstanceOptions<Mode> = {
|
|
46
|
+
...options.instanceOptions,
|
|
47
|
+
mode,
|
|
48
|
+
initialState,
|
|
49
|
+
config,
|
|
50
|
+
};
|
|
51
|
+
const { root } = new PrimaryInstance(primaryInstanceOptions);
|
|
52
|
+
|
|
53
|
+
this.mode = mode;
|
|
54
|
+
this.root = root;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FormResultStatus,
|
|
3
|
+
LoadFormFailureResult,
|
|
4
|
+
LoadFormResult,
|
|
5
|
+
LoadFormSuccessResult,
|
|
6
|
+
LoadFormWarningResult,
|
|
7
|
+
} from '../../client/form/LoadFormResult.ts';
|
|
8
|
+
|
|
9
|
+
interface LoadFormResultByStatus {
|
|
10
|
+
readonly success: LoadFormSuccessResult;
|
|
11
|
+
readonly warning: LoadFormWarningResult;
|
|
12
|
+
readonly failure: LoadFormFailureResult;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type BaseFormResultProperty<
|
|
16
|
+
Status extends FormResultStatus,
|
|
17
|
+
Key extends keyof LoadFormResult,
|
|
18
|
+
> = LoadFormResultByStatus[Status][Key];
|
|
19
|
+
|
|
20
|
+
export interface BaseFormResultOptions<Status extends FormResultStatus> {
|
|
21
|
+
readonly status: Status;
|
|
22
|
+
readonly warnings: BaseFormResultProperty<Status, 'warnings'>;
|
|
23
|
+
readonly error: BaseFormResultProperty<Status, 'error'>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export abstract class BaseFormResult<Status extends FormResultStatus> {
|
|
27
|
+
readonly status: Status;
|
|
28
|
+
readonly warnings: BaseFormResultProperty<Status, 'warnings'>;
|
|
29
|
+
readonly error: BaseFormResultProperty<Status, 'error'>;
|
|
30
|
+
|
|
31
|
+
abstract readonly createInstance: BaseFormResultProperty<Status, 'createInstance'>;
|
|
32
|
+
abstract readonly editInstance: BaseFormResultProperty<Status, 'editInstance'>;
|
|
33
|
+
abstract readonly restoreInstance: BaseFormResultProperty<Status, 'restoreInstance'>;
|
|
34
|
+
|
|
35
|
+
constructor(options: BaseFormResultOptions<Status>) {
|
|
36
|
+
this.status = options.status;
|
|
37
|
+
this.warnings = options.warnings;
|
|
38
|
+
this.error = options.error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { CreateFormInstance } from '../../client/form/CreateFormInstance.ts';
|
|
2
|
+
import type {
|
|
3
|
+
EditFormInstance,
|
|
4
|
+
EditFormInstanceInput,
|
|
5
|
+
} from '../../client/form/EditFormInstance.ts';
|
|
6
|
+
import type { FormInstanceConfig } from '../../client/form/FormInstanceConfig.ts';
|
|
7
|
+
import type { FormResultStatus } from '../../client/form/LoadFormResult.ts';
|
|
8
|
+
import type {
|
|
9
|
+
RestoreFormInstance,
|
|
10
|
+
RestoreFormInstanceInput,
|
|
11
|
+
} from '../../client/form/RestoreFormInstance.ts';
|
|
12
|
+
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
13
|
+
import { InitialInstanceState } from '../../instance/input/InitialInstanceState.ts';
|
|
14
|
+
import type { BasePrimaryInstanceOptions } from '../../instance/PrimaryInstance.ts';
|
|
15
|
+
import type { FormResource } from '../../instance/resource.ts';
|
|
16
|
+
import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
|
|
17
|
+
import type { InstantiableFormResult } from '../FormInstance.ts';
|
|
18
|
+
import { FormInstance } from '../FormInstance.ts';
|
|
19
|
+
import type { BaseFormResultProperty } from './BaseFormResult.ts';
|
|
20
|
+
import { BaseFormResult } from './BaseFormResult.ts';
|
|
21
|
+
|
|
22
|
+
// prettier-ignore
|
|
23
|
+
export type InstantiableFormResultStatus =
|
|
24
|
+
| 'success'
|
|
25
|
+
| 'warning';
|
|
26
|
+
|
|
27
|
+
export interface BaseInstantiableFormResultOptions<Status extends InstantiableFormResultStatus> {
|
|
28
|
+
readonly status: Status;
|
|
29
|
+
readonly warnings: BaseFormResultProperty<Status, 'warnings'>;
|
|
30
|
+
readonly error: null;
|
|
31
|
+
readonly scope: ReactiveScope;
|
|
32
|
+
readonly formResource: FormResource;
|
|
33
|
+
readonly instanceOptions: BasePrimaryInstanceOptions;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export abstract class BaseInstantiableFormResult<
|
|
37
|
+
Status extends InstantiableFormResultStatus,
|
|
38
|
+
> extends BaseFormResult<Status> {
|
|
39
|
+
readonly createInstance: CreateFormInstance;
|
|
40
|
+
readonly editInstance: EditFormInstance;
|
|
41
|
+
readonly restoreInstance: RestoreFormInstance;
|
|
42
|
+
|
|
43
|
+
constructor(options: BaseInstantiableFormResultOptions<Status>) {
|
|
44
|
+
const { status, warnings, error, instanceOptions } = options;
|
|
45
|
+
|
|
46
|
+
super({
|
|
47
|
+
status,
|
|
48
|
+
warnings,
|
|
49
|
+
error,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
this.createInstance = (instanceConfig: FormInstanceConfig = {}) => {
|
|
53
|
+
this.assertInstantiable();
|
|
54
|
+
|
|
55
|
+
return new FormInstance(this, {
|
|
56
|
+
mode: 'create',
|
|
57
|
+
instanceOptions,
|
|
58
|
+
initialState: null,
|
|
59
|
+
instanceConfig,
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
this.editInstance = async (
|
|
64
|
+
input: EditFormInstanceInput,
|
|
65
|
+
instanceConfig: FormInstanceConfig = {}
|
|
66
|
+
) => {
|
|
67
|
+
this.assertInstantiable();
|
|
68
|
+
|
|
69
|
+
const initialState = await InitialInstanceState.resolve(instanceOptions.model, input);
|
|
70
|
+
|
|
71
|
+
return new FormInstance(this, {
|
|
72
|
+
mode: 'edit',
|
|
73
|
+
instanceOptions,
|
|
74
|
+
initialState,
|
|
75
|
+
instanceConfig,
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
this.restoreInstance = async (
|
|
80
|
+
input: RestoreFormInstanceInput,
|
|
81
|
+
instanceConfig: FormInstanceConfig = {}
|
|
82
|
+
) => {
|
|
83
|
+
this.assertInstantiable();
|
|
84
|
+
|
|
85
|
+
const initialState = await InitialInstanceState.from(instanceOptions.model, input.data);
|
|
86
|
+
|
|
87
|
+
return new FormInstance(this, {
|
|
88
|
+
mode: 'restore',
|
|
89
|
+
instanceOptions,
|
|
90
|
+
initialState,
|
|
91
|
+
instanceConfig,
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
isInstantiable(): this is InstantiableFormResult {
|
|
97
|
+
const self: BaseFormResult<FormResultStatus> = this satisfies BaseFormResult<FormResultStatus>;
|
|
98
|
+
|
|
99
|
+
return self.status !== 'failure';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
assertInstantiable(): asserts this is InstantiableFormResult {
|
|
103
|
+
if (!this.isInstantiable()) {
|
|
104
|
+
throw new ErrorProductionDesignPendingError(
|
|
105
|
+
'Failed to instantiate from result with status: "failure"'
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AnyFunction } from '@getodk/common/types/helpers.js';
|
|
2
|
+
import type { CreateFormInstance } from '../../client/form/CreateFormInstance.ts';
|
|
3
|
+
import type { EditFormInstance } from '../../client/form/EditFormInstance.ts';
|
|
4
|
+
import type {
|
|
5
|
+
FailedLoadFormResultMethod,
|
|
6
|
+
LoadFormFailureResult,
|
|
7
|
+
LoadFormWarnings,
|
|
8
|
+
} from '../../client/form/LoadFormResult.ts';
|
|
9
|
+
import type { RestoreFormInstance } from '../../client/form/RestoreFormInstance.ts';
|
|
10
|
+
import { LoadFormFailureError } from '../../error/LoadFormFailureError.ts';
|
|
11
|
+
import { BaseFormResult } from './BaseFormResult.ts';
|
|
12
|
+
|
|
13
|
+
interface FormFailureOptions {
|
|
14
|
+
readonly error: LoadFormFailureError;
|
|
15
|
+
readonly warnings: LoadFormWarnings | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const failedFormResultMethodFactory = <T extends AnyFunction>(
|
|
19
|
+
cause: LoadFormFailureError
|
|
20
|
+
): FailedLoadFormResultMethod<T> => {
|
|
21
|
+
return () => {
|
|
22
|
+
throw new Error(cause.message, { cause });
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export class FormFailureResult extends BaseFormResult<'failure'> implements LoadFormFailureResult {
|
|
27
|
+
readonly createInstance: FailedLoadFormResultMethod<CreateFormInstance>;
|
|
28
|
+
readonly editInstance: FailedLoadFormResultMethod<EditFormInstance>;
|
|
29
|
+
readonly restoreInstance: FailedLoadFormResultMethod<RestoreFormInstance>;
|
|
30
|
+
|
|
31
|
+
constructor(options: FormFailureOptions) {
|
|
32
|
+
const { error, warnings } = options;
|
|
33
|
+
|
|
34
|
+
super({
|
|
35
|
+
status: 'failure',
|
|
36
|
+
warnings,
|
|
37
|
+
error,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
this.createInstance = failedFormResultMethodFactory(error);
|
|
41
|
+
this.editInstance = failedFormResultMethodFactory(error);
|
|
42
|
+
this.restoreInstance = failedFormResultMethodFactory(error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LoadFormSuccessResult } from '../../client/index.ts';
|
|
2
|
+
import type { BasePrimaryInstanceOptions } from '../../instance/PrimaryInstance.ts';
|
|
3
|
+
import type { FormResource } from '../../instance/resource.ts';
|
|
4
|
+
import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
|
|
5
|
+
import { BaseInstantiableFormResult } from './BaseInstantiableFormResult.ts';
|
|
6
|
+
|
|
7
|
+
export interface FormSuccessResultOptions {
|
|
8
|
+
readonly warnings: null;
|
|
9
|
+
readonly error: null;
|
|
10
|
+
readonly scope: ReactiveScope;
|
|
11
|
+
readonly formResource: FormResource;
|
|
12
|
+
readonly instanceOptions: BasePrimaryInstanceOptions;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class FormSuccessResult
|
|
16
|
+
extends BaseInstantiableFormResult<'success'>
|
|
17
|
+
implements LoadFormSuccessResult
|
|
18
|
+
{
|
|
19
|
+
constructor(options: FormSuccessResultOptions) {
|
|
20
|
+
super({
|
|
21
|
+
status: 'success',
|
|
22
|
+
...options,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LoadFormWarningResult, LoadFormWarnings } from '../../client/form/LoadFormResult.ts';
|
|
2
|
+
import type { BasePrimaryInstanceOptions } from '../../instance/PrimaryInstance.ts';
|
|
3
|
+
import type { FormResource } from '../../instance/resource.ts';
|
|
4
|
+
import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
|
|
5
|
+
import { BaseInstantiableFormResult } from './BaseInstantiableFormResult.ts';
|
|
6
|
+
|
|
7
|
+
export interface FormWarningResultOptions {
|
|
8
|
+
readonly warnings: LoadFormWarnings;
|
|
9
|
+
readonly error: null;
|
|
10
|
+
readonly scope: ReactiveScope;
|
|
11
|
+
readonly formResource: FormResource;
|
|
12
|
+
readonly instanceOptions: BasePrimaryInstanceOptions;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class FormWarningResult
|
|
16
|
+
extends BaseInstantiableFormResult<'warning'>
|
|
17
|
+
implements LoadFormWarningResult
|
|
18
|
+
{
|
|
19
|
+
constructor(options: FormWarningResultOptions) {
|
|
20
|
+
super({
|
|
21
|
+
status: 'warning',
|
|
22
|
+
...options,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CreatedFormInstance } from '../client/form/CreateFormInstance.ts';
|
|
2
|
+
import type { FormInstanceConfig } from '../client/form/FormInstanceConfig.ts';
|
|
3
|
+
import type { LoadFormOptions } from '../client/form/LoadForm.ts';
|
|
4
|
+
import type { FormResource } from '../instance/resource.ts';
|
|
5
|
+
import { loadForm } from './loadForm.ts';
|
|
6
|
+
|
|
7
|
+
export interface CreateInstanceOptions {
|
|
8
|
+
readonly form?: LoadFormOptions;
|
|
9
|
+
readonly instance?: FormInstanceConfig;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const createInstance = async (
|
|
13
|
+
formResource: FormResource,
|
|
14
|
+
options?: CreateInstanceOptions
|
|
15
|
+
): Promise<CreatedFormInstance> => {
|
|
16
|
+
const form = await loadForm(formResource, options?.form);
|
|
17
|
+
|
|
18
|
+
if (form.status === 'failure') {
|
|
19
|
+
throw form.error;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return form.createInstance(options?.instance);
|
|
23
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { EditedFormInstance, EditFormInstanceInput } from '../client/form/EditFormInstance.ts';
|
|
2
|
+
import type { FormInstanceConfig } from '../client/form/FormInstanceConfig.ts';
|
|
3
|
+
import type { LoadFormOptions } from '../client/form/LoadForm.ts';
|
|
4
|
+
import type { FormResource } from '../instance/resource.ts';
|
|
5
|
+
import { loadForm } from './loadForm.ts';
|
|
6
|
+
|
|
7
|
+
export interface EditInstanceOptions {
|
|
8
|
+
readonly form?: LoadFormOptions;
|
|
9
|
+
readonly instance?: FormInstanceConfig;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const editInstance = async (
|
|
13
|
+
formResource: FormResource,
|
|
14
|
+
input: EditFormInstanceInput,
|
|
15
|
+
options?: EditInstanceOptions
|
|
16
|
+
): Promise<EditedFormInstance> => {
|
|
17
|
+
const form = await loadForm(formResource, options?.form);
|
|
18
|
+
|
|
19
|
+
if (form.status === 'failure') {
|
|
20
|
+
throw form.error;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return form.editInstance(input, options?.instance);
|
|
24
|
+
};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { Owner } from 'solid-js';
|
|
2
|
+
import { getOwner } from 'solid-js';
|
|
3
|
+
import { MISSING_RESOURCE_BEHAVIOR } from '../client/constants.ts';
|
|
4
|
+
import type { FormResource } from '../client/form/FormResource.ts';
|
|
5
|
+
import type { LoadForm, LoadFormOptions } from '../client/form/LoadForm.ts';
|
|
6
|
+
import type { LoadFormResult } from '../client/form/LoadFormResult.ts';
|
|
7
|
+
import { LoadFormFailureError } from '../error/LoadFormFailureError.ts';
|
|
8
|
+
import { retrieveFormDefinition } from '../instance/resource.ts';
|
|
9
|
+
import type { ReactiveScope } from '../lib/reactivity/scope.ts';
|
|
10
|
+
import { createReactiveScope } from '../lib/reactivity/scope.ts';
|
|
11
|
+
import { XFormDOM } from '../parse/XFormDOM.ts';
|
|
12
|
+
import { XFormDefinition } from '../parse/XFormDefinition.ts';
|
|
13
|
+
import { SecondaryInstancesDefinition } from '../parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts';
|
|
14
|
+
import { FormFailureResult } from './FormResult/FormFailureResult.ts';
|
|
15
|
+
import { FormSuccessResult } from './FormResult/FormSuccessResult.ts';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Creates a {@link ReactiveScope | reactive scope} from which all form
|
|
19
|
+
* instances derive, and:
|
|
20
|
+
*
|
|
21
|
+
* - if a client loads a form within a Solid reactive context, the scope will be
|
|
22
|
+
* disposed along with the client's reactive context; OR
|
|
23
|
+
* - if a client loads a form outside a Solid reactive context (typically: if a
|
|
24
|
+
* client does not use Solid reactivity), the scope will disposed if and when
|
|
25
|
+
* the engine drops access to the loaded form
|
|
26
|
+
*
|
|
27
|
+
* **IMPORTANT:** this **MUST** be called synchronously. If it is called in an
|
|
28
|
+
* `async` function, it **MUST** be called before any `await` expression; if it
|
|
29
|
+
* is called in any other flow with mixed synchrony, it must be called before
|
|
30
|
+
* yielding to the event loop. Failing to do this will cause the engine to lose
|
|
31
|
+
* access to a client's Solid reactive context, potentially leaking form
|
|
32
|
+
* reactivity indefinitely.
|
|
33
|
+
*/
|
|
34
|
+
const createPotentiallyClientOwnedReactiveScope = (): ReactiveScope => {
|
|
35
|
+
/**
|
|
36
|
+
* A {@link clientOwner | client owner} is the owner of a client's Solid
|
|
37
|
+
* reactive context, if one exists. If none exists, the {@link ReactiveScope}
|
|
38
|
+
* is fully owned by the engine.
|
|
39
|
+
*/
|
|
40
|
+
const clientOwner: Owner | null = getOwner();
|
|
41
|
+
|
|
42
|
+
return createReactiveScope({ owner: clientOwner });
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type GlobalFetch = typeof globalThis.fetch;
|
|
46
|
+
|
|
47
|
+
type UnboundGlobalFetch = (this: void, ...args: Parameters<GlobalFetch>) => ReturnType<GlobalFetch>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @see {@link https://github.com/getodk/web-forms/pull/281}
|
|
51
|
+
*/
|
|
52
|
+
let unboundGlobalFetch: UnboundGlobalFetch;
|
|
53
|
+
|
|
54
|
+
if (typeof globalThis.fetch === 'function') {
|
|
55
|
+
unboundGlobalFetch = (...args) => {
|
|
56
|
+
return globalThis.fetch(...args);
|
|
57
|
+
};
|
|
58
|
+
} else {
|
|
59
|
+
unboundGlobalFetch = () => {
|
|
60
|
+
throw new Error('fetch is not supported in this environment');
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface ResolvedOptions extends Required<LoadFormOptions> {}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Resolves {@link FormResultLoadOptions} from options directly passed by a
|
|
68
|
+
* client (if passed at all).
|
|
69
|
+
*
|
|
70
|
+
* Note that this function exists to be more resilient than the static types
|
|
71
|
+
* would technically require, i.e. anticipating any kind of nullish value where
|
|
72
|
+
* option properties are typed only as optional. This is an acknowledgement that
|
|
73
|
+
* the nuances of nullishness are a footgun in untyped JavaScript, and
|
|
74
|
+
* nested-optional semantics are a particularly likely source of mistakes in
|
|
75
|
+
* client, and especially host application, integrations.
|
|
76
|
+
*/
|
|
77
|
+
const resolveOptions = (options?: LoadFormOptions): ResolvedOptions => {
|
|
78
|
+
return {
|
|
79
|
+
fetchFormDefinition: options?.fetchFormDefinition ?? unboundGlobalFetch,
|
|
80
|
+
fetchFormAttachment: options?.fetchFormAttachment ?? unboundGlobalFetch,
|
|
81
|
+
missingResourceBehavior: options?.missingResourceBehavior ?? MISSING_RESOURCE_BEHAVIOR.DEFAULT,
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* **IMPORTANT:** This function is defined separately from, and to be called by,
|
|
87
|
+
* the {@link loadForm} entrypoint to ensure we satisfy the synchrony
|
|
88
|
+
* requirements of {@link createPotentiallyClientOwnedReactiveScope}.
|
|
89
|
+
*/
|
|
90
|
+
const loadFormResult = async (
|
|
91
|
+
scope: ReactiveScope,
|
|
92
|
+
formResource: FormResource,
|
|
93
|
+
options: ResolvedOptions
|
|
94
|
+
): Promise<LoadFormResult> => {
|
|
95
|
+
const { fetchFormDefinition, fetchFormAttachment, missingResourceBehavior } = options;
|
|
96
|
+
|
|
97
|
+
// TODO: Currently, **all** of the intermediate calls in this `try` block
|
|
98
|
+
// may throw! Handling that fact at the source would provide a much more
|
|
99
|
+
// specific `LoadFormFailureResult`, and address performance regressions
|
|
100
|
+
// inherent to such a broad/mixed use of `try`/`catch`.
|
|
101
|
+
//
|
|
102
|
+
// Addressing this is deferred for now, to limit scope.
|
|
103
|
+
try {
|
|
104
|
+
const sourceXML = await retrieveFormDefinition(formResource, {
|
|
105
|
+
fetchFormDefinition,
|
|
106
|
+
});
|
|
107
|
+
const xformDOM = XFormDOM.from(sourceXML);
|
|
108
|
+
const { model } = new XFormDefinition(xformDOM);
|
|
109
|
+
const secondaryInstances = await SecondaryInstancesDefinition.load(xformDOM, {
|
|
110
|
+
fetchResource: fetchFormAttachment,
|
|
111
|
+
missingResourceBehavior,
|
|
112
|
+
});
|
|
113
|
+
const instanceOptions = {
|
|
114
|
+
scope,
|
|
115
|
+
model,
|
|
116
|
+
secondaryInstances,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return new FormSuccessResult({
|
|
120
|
+
warnings: null,
|
|
121
|
+
error: null,
|
|
122
|
+
scope,
|
|
123
|
+
formResource,
|
|
124
|
+
instanceOptions,
|
|
125
|
+
});
|
|
126
|
+
} catch (caught) {
|
|
127
|
+
let cause: Error;
|
|
128
|
+
|
|
129
|
+
if (caught instanceof Error) {
|
|
130
|
+
cause = caught;
|
|
131
|
+
} else {
|
|
132
|
+
cause = new Error('Unknown form load error', { cause: caught });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const error = new LoadFormFailureError(formResource, [cause]);
|
|
136
|
+
|
|
137
|
+
return new FormFailureResult({
|
|
138
|
+
warnings: null,
|
|
139
|
+
error,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const loadForm = (
|
|
145
|
+
formResource: FormResource,
|
|
146
|
+
options?: LoadFormOptions
|
|
147
|
+
): Promise<LoadFormResult> => {
|
|
148
|
+
const scope = createPotentiallyClientOwnedReactiveScope();
|
|
149
|
+
const resolvedOptions = resolveOptions(options);
|
|
150
|
+
|
|
151
|
+
return loadFormResult(scope, formResource, resolvedOptions);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
loadForm satisfies LoadForm;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FormInstanceConfig } from '../client/form/FormInstanceConfig.ts';
|
|
2
|
+
import type { LoadFormOptions } from '../client/form/LoadForm.ts';
|
|
3
|
+
import type {
|
|
4
|
+
RestoredFormInstance,
|
|
5
|
+
RestoreFormInstanceInput,
|
|
6
|
+
} from '../client/form/RestoreFormInstance.ts';
|
|
7
|
+
import type { FormResource } from '../instance/resource.ts';
|
|
8
|
+
import { loadForm } from './loadForm.ts';
|
|
9
|
+
|
|
10
|
+
export interface RestoreInstanceOptions {
|
|
11
|
+
readonly form?: LoadFormOptions;
|
|
12
|
+
readonly instance?: FormInstanceConfig;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const restoreInstance = async (
|
|
16
|
+
formResource: FormResource,
|
|
17
|
+
input: RestoreFormInstanceInput,
|
|
18
|
+
options?: RestoreInstanceOptions
|
|
19
|
+
): Promise<RestoredFormInstance> => {
|
|
20
|
+
const form = await loadForm(formResource, options?.form);
|
|
21
|
+
|
|
22
|
+
if (form.status === 'failure') {
|
|
23
|
+
throw form.error;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return form.restoreInstance(input, options?.instance);
|
|
27
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { UnknownObject } from '@getodk/common/lib/type-assertions/assertUnknownObject.ts';
|
|
2
|
+
import type { Primitive } from '@getodk/common/types/Primitive.ts';
|
|
3
|
+
import type { FormResource } from '../client/form/FormResource.ts';
|
|
4
|
+
|
|
5
|
+
// prettier-ignore
|
|
6
|
+
type PartiallyKnownType<T> =
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
8
|
+
| T
|
|
9
|
+
| UnknownObject
|
|
10
|
+
| Primitive;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A {@link Blob}, which _may be_ a {@link File}.
|
|
14
|
+
*
|
|
15
|
+
* Extends {@link Blob} with optional properties corresponding to {@link File}'s
|
|
16
|
+
* own extensions of the same interface, allowing inspection without an
|
|
17
|
+
* unnecessary type cast, and without unnecessary runtime/type reconciliation.
|
|
18
|
+
*
|
|
19
|
+
* @todo There's almost certainly no reason that this couldn't be a part of the
|
|
20
|
+
* client-facing {@link FormResource} union type. It's kept internal here for
|
|
21
|
+
* now, in case that could cause confusion in client integrations.
|
|
22
|
+
*/
|
|
23
|
+
interface MaybeFile extends Blob {
|
|
24
|
+
readonly lastModified?: PartiallyKnownType<number>;
|
|
25
|
+
readonly name?: PartiallyKnownType<string>;
|
|
26
|
+
readonly webkitRelativePath?: PartiallyKnownType<string>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const blobDescription = (resource: MaybeFile): string => {
|
|
30
|
+
const { name } = resource;
|
|
31
|
+
|
|
32
|
+
if (typeof name === 'string') {
|
|
33
|
+
return name;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let commonConstructorName: 'Blob' | 'File';
|
|
37
|
+
|
|
38
|
+
if (resource instanceof File) {
|
|
39
|
+
commonConstructorName = 'File';
|
|
40
|
+
} else {
|
|
41
|
+
commonConstructorName = 'Blob';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return `Unknown ${commonConstructorName} data`;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
interface FormResourceMetadata {
|
|
48
|
+
readonly description: string;
|
|
49
|
+
readonly rawData: string | null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const formResourceMetadata = (resource: FormResource): FormResourceMetadata => {
|
|
53
|
+
if (resource instanceof Blob) {
|
|
54
|
+
return {
|
|
55
|
+
description: blobDescription(resource),
|
|
56
|
+
rawData: null,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (resource instanceof URL) {
|
|
61
|
+
return {
|
|
62
|
+
description: resource.href,
|
|
63
|
+
rawData: null,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
description: 'Raw string data',
|
|
69
|
+
rawData: resource,
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @todo This is a placeholder class, given a name so it can be referenced in
|
|
75
|
+
* client interfaces for form loading. It is pending design of errors (broadly)
|
|
76
|
+
* and modeling of form loading errors (specifically).
|
|
77
|
+
*/
|
|
78
|
+
export class LoadFormFailureError extends AggregateError {
|
|
79
|
+
constructor(resource: FormResource, errors: readonly Error[]) {
|
|
80
|
+
const { description, rawData } = formResourceMetadata(resource);
|
|
81
|
+
const messageLines: string[] = [
|
|
82
|
+
`Failed to load form resource: ${description}`,
|
|
83
|
+
'\n',
|
|
84
|
+
|
|
85
|
+
...errors.map((error) => {
|
|
86
|
+
const aggregatedMessage = error.message;
|
|
87
|
+
|
|
88
|
+
if (aggregatedMessage == null) {
|
|
89
|
+
return '- Unknown error';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return `- ${aggregatedMessage}`;
|
|
93
|
+
}),
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
if (rawData != null) {
|
|
97
|
+
messageLines.push('\n- - -\n', 'Raw resource data:', rawData);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const message = messageLines.join('\n');
|
|
101
|
+
|
|
102
|
+
super(errors, message);
|
|
103
|
+
|
|
104
|
+
const [head, ...tail] = errors;
|
|
105
|
+
|
|
106
|
+
if (head != null && tail.length === 0) {
|
|
107
|
+
const { stack } = head;
|
|
108
|
+
|
|
109
|
+
if (typeof stack === 'string') {
|
|
110
|
+
this.stack = stack;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|